| 49 | } |
| 50 | |
| 51 | static std::unique_ptr<TextRun> MakeTextRun(const std::vector<Glyph*>& glyphs) { |
| 52 | if (glyphs.empty()) { |
| 53 | return nullptr; |
| 54 | } |
| 55 | auto textRun = new TextRun(); |
| 56 | auto firstGlyph = glyphs[0]; |
| 57 | // Creates text paints. |
| 58 | textRun->paints[0] = CreateFillPaint(firstGlyph).release(); |
| 59 | textRun->paints[1] = CreateStrokePaint(firstGlyph).release(); |
| 60 | auto textStyle = firstGlyph->getStyle(); |
| 61 | if ((textStyle == TextStyle::StrokeAndFill && !firstGlyph->getStrokeOverFill()) || |
| 62 | textRun->paints[0] == nullptr) { |
| 63 | std::swap(textRun->paints[0], textRun->paints[1]); |
| 64 | } |
| 65 | // Creates text blob. |
| 66 | auto noTranslateMatrix = firstGlyph->getTotalMatrix(); |
| 67 | noTranslateMatrix.setTranslateX(0); |
| 68 | noTranslateMatrix.setTranslateY(0); |
| 69 | textRun->matrix = noTranslateMatrix; |
| 70 | noTranslateMatrix.invert(&noTranslateMatrix); |
| 71 | std::vector<tgfx::GlyphID> glyphIDs = {}; |
| 72 | std::vector<tgfx::Point> positions = {}; |
| 73 | for (auto& glyph : glyphs) { |
| 74 | auto m = glyph->getTotalMatrix(); |
| 75 | m.postConcat(noTranslateMatrix); |
| 76 | for (auto& glyphID : glyph->getGlyphIDs()) { |
| 77 | glyphIDs.push_back(glyphID); |
| 78 | positions.push_back({m.getTranslateX(), m.getTranslateY()}); |
| 79 | } |
| 80 | } |
| 81 | textRun->textFont = firstGlyph->getFont(); |
| 82 | textRun->glyphIDs = glyphIDs; |
| 83 | textRun->positions = positions; |
| 84 | return std::unique_ptr<TextRun>(textRun); |
| 85 | } |
| 86 | |
| 87 | std::shared_ptr<Graphic> Text::MakeFrom(const std::vector<GlyphHandle>& glyphs, |
| 88 | std::shared_ptr<TextBlock> textBlock, |
no test coverage detected