| 705 | } |
| 706 | |
| 707 | void PiuTextFormat(PiuText* self) |
| 708 | { |
| 709 | xsMachine *the = (*self)->the; |
| 710 | PiuTextBuffer* nodeBuffer = (*self)->nodeBuffer; |
| 711 | PiuTextOffset nodeOffset = sizeof(PiuTextBufferRecord); |
| 712 | PiuTextOffset nodeLimit = (PiuTextOffset)(*nodeBuffer)->current; |
| 713 | PiuTextFormatContextRecord _ctx; |
| 714 | PiuTextFormatContext ctx = &_ctx; |
| 715 | PiuCoordinate marginTop; |
| 716 | PiuCoordinate marginBottom = 0; |
| 717 | c_memset(ctx, 0, sizeof(PiuTextFormatContextRecord)); |
| 718 | PiuTextBufferClear(the, (*self)->lineBuffer); |
| 719 | while (nodeOffset < nodeLimit) { |
| 720 | switch (KIND(nodeOffset)) { |
| 721 | case piuTextNodeBeginBlockKind: { |
| 722 | PiuTextNodeBegin nodeBegin = NODE(nodeOffset); |
| 723 | ctx->blockStyle = ctx->spanStyle = nodeBegin->computedStyle; |
| 724 | ctx->blockWidth = (*self)->textWidth - (*ctx->blockStyle)->margins.left - (*ctx->blockStyle)->margins.right; |
| 725 | marginTop = (*ctx->blockStyle)->margins.top; |
| 726 | ctx->y += (marginTop > marginBottom) ? marginTop : marginBottom; |
| 727 | nodeOffset += sizeof(PiuTextNodeBeginRecord); |
| 728 | } break; |
| 729 | case piuTextNodeBeginSpanKind: { |
| 730 | PiuTextNodeBegin nodeBegin = NODE(nodeOffset); |
| 731 | ctx->spanStyle = nodeBegin->computedStyle; |
| 732 | nodeOffset += sizeof(PiuTextNodeBeginRecord); |
| 733 | } break; |
| 734 | case piuTextNodeEndBlockKind: { |
| 735 | PiuTextNodeEnd nodeEnd = NODE(nodeOffset); |
| 736 | PiuTextFormatBlock(self, ctx, piuTextReturn, 0, nodeEnd->parentOffset); |
| 737 | marginBottom = (*ctx->blockStyle)->margins.bottom; |
| 738 | ctx->blockStyle = ctx->spanStyle = NULL; |
| 739 | nodeOffset += sizeof(PiuTextNodeEndRecord); |
| 740 | } break; |
| 741 | case piuTextNodeEndSpanKind: { |
| 742 | PiuTextNodeEnd nodeEnd = NODE(nodeOffset); |
| 743 | PiuTextNodeBegin nodeBegin = NODE(nodeEnd->parentOffset); |
| 744 | ctx->spanStyle = nodeBegin->computedStyle; |
| 745 | nodeOffset += sizeof(PiuTextNodeEndRecord); |
| 746 | } break; |
| 747 | case piuTextNodeStringKind: { |
| 748 | PiuTextNodeString node = NODE(nodeOffset); |
| 749 | PiuTextOffset previousOffset = 0, offset = 0, nextOffset, textOffset = node->fromOffset; |
| 750 | PiuFont* spanFont = (*ctx->spanStyle)->font; |
| 751 | PiuCoordinate spanAscent = PiuFontGetAscent(spanFont); |
| 752 | PiuCoordinate spanHeight = PiuFontGetHeight(spanFont); |
| 753 | for (;;) { |
| 754 | PiuTextKind kind = PiuTextAdvance(the, node->string, offset, 0x7fff, &nextOffset); |
| 755 | if (kind) { |
| 756 | PiuTextOffset length = offset - previousOffset; |
| 757 | if (length) { |
| 758 | ctx->wordWidth += PiuFontGetWidth(spanFont, node->string, previousOffset, length); |
| 759 | if (ctx->wordAscent < spanAscent) |
| 760 | ctx->wordAscent = spanAscent; |
| 761 | if (ctx->wordHeight < spanHeight) |
| 762 | ctx->wordHeight = spanHeight; |
| 763 | previousOffset = offset; |
| 764 | } |
no test coverage detected