Пример #1
0
void Font::drawEmphasisMarks(GraphicsContext* context, const TextRun& run, const GlyphBuffer& glyphBuffer, const AtomicString& mark, const FloatPoint& point) const
{
    FontCachePurgePreventer purgePreventer;
    
    GlyphData markGlyphData;
    if (!getEmphasisMarkGlyphData(mark, markGlyphData))
        return;

    const SimpleFontData* markFontData = markGlyphData.fontData;
    ASSERT(markFontData);
    if (!markFontData)
        return;

    Glyph markGlyph = markGlyphData.glyph;
    Glyph spaceGlyph = markFontData->spaceGlyph();

    float middleOfLastGlyph = offsetToMiddleOfGlyphAtIndex(glyphBuffer, 0);
    FloatPoint startPoint(point.x() + middleOfLastGlyph - offsetToMiddleOfGlyph(markFontData, markGlyph), point.y());

    GlyphBuffer markBuffer;
    for (int i = 0; i + 1 < glyphBuffer.size(); ++i) {
        float middleOfNextGlyph = offsetToMiddleOfGlyphAtIndex(glyphBuffer, i + 1);
        float advance = glyphBuffer.advanceAt(i).width() - middleOfLastGlyph + middleOfNextGlyph;
        markBuffer.add(glyphBuffer.glyphAt(i) ? markGlyph : spaceGlyph, markFontData, advance);
        middleOfLastGlyph = middleOfNextGlyph;
    }
    markBuffer.add(glyphBuffer.glyphAt(glyphBuffer.size() - 1) ? markGlyph : spaceGlyph, markFontData, 0);

    drawGlyphBuffer(context, run, markBuffer, startPoint);
}
Пример #2
0
TEST(GlyphBufferTest, StoresVerticalOffsets) {
  RefPtr<SimpleFontData> font1 = TestSimpleFontData::create();
  RefPtr<SimpleFontData> font2 = TestSimpleFontData::create();

  GlyphBuffer glyphBuffer;
  EXPECT_FALSE(glyphBuffer.hasVerticalOffsets());

  glyphBuffer.add(42, font1.get(), FloatPoint(10, 0));
  glyphBuffer.add(43, font1.get(), FloatPoint(15, 0));
  glyphBuffer.add(44, font2.get(), FloatPoint(12, 2));

  EXPECT_FALSE(glyphBuffer.isEmpty());
  EXPECT_TRUE(glyphBuffer.hasVerticalOffsets());
  EXPECT_EQ(3u, glyphBuffer.size());

  const float* offsets = glyphBuffer.offsets(0);
  EXPECT_EQ(10, glyphBuffer.xOffsetAt(0));
  EXPECT_EQ(0, glyphBuffer.yOffsetAt(0));
  EXPECT_EQ(15, glyphBuffer.xOffsetAt(1));
  EXPECT_EQ(0, glyphBuffer.yOffsetAt(1));
  EXPECT_EQ(12, glyphBuffer.xOffsetAt(2));
  EXPECT_EQ(2, glyphBuffer.yOffsetAt(2));

  EXPECT_EQ(10, offsets[0]);
  EXPECT_EQ(0, offsets[1]);
  EXPECT_EQ(15, offsets[2]);
  EXPECT_EQ(0, offsets[3]);
  EXPECT_EQ(12, offsets[4]);
  EXPECT_EQ(2, offsets[5]);
}
Пример #3
0
TEST(GlyphBufferTest, ReverseForSimpleRTL) {
  RefPtr<SimpleFontData> font1 = TestSimpleFontData::create();
  RefPtr<SimpleFontData> font2 = TestSimpleFontData::create();

  GlyphBuffer glyphBuffer;
  glyphBuffer.add(42, font1.get(), 10);
  glyphBuffer.add(43, font1.get(), 15);
  glyphBuffer.add(44, font2.get(), 25);

  EXPECT_FALSE(glyphBuffer.isEmpty());
  EXPECT_EQ(3u, glyphBuffer.size());

  glyphBuffer.reverseForSimpleRTL(30, 100);

  EXPECT_FALSE(glyphBuffer.isEmpty());
  EXPECT_EQ(3u, glyphBuffer.size());
  EXPECT_EQ(44, glyphBuffer.glyphAt(0));
  EXPECT_EQ(43, glyphBuffer.glyphAt(1));
  EXPECT_EQ(42, glyphBuffer.glyphAt(2));
  EXPECT_EQ(font2.get(), glyphBuffer.fontDataAt(0));
  EXPECT_EQ(font1.get(), glyphBuffer.fontDataAt(1));
  EXPECT_EQ(font1.get(), glyphBuffer.fontDataAt(2));
  EXPECT_EQ(70, glyphBuffer.xOffsetAt(0));
  EXPECT_EQ(75, glyphBuffer.xOffsetAt(1));
  EXPECT_EQ(85, glyphBuffer.xOffsetAt(2));
}
Пример #4
0
inline GlyphBuffer DrawGlyphs::generateGlyphBuffer() const
{
    GlyphBuffer result;
    for (size_t i = 0; i < m_glyphs.size(); ++i) {
#if USE(CAIRO)
        result.add(m_glyphs[i].index, &m_font.get(), m_advances[i]);
#else
        result.add(m_glyphs[i], &m_font.get(), m_advances[i]);
#endif
    }
    return result;
}
Пример #5
0
float Font::getGlyphsAndAdvancesForSimpleText(const TextRun& run, int from, int to, GlyphBuffer& glyphBuffer, ForTextEmphasisOrNot forTextEmphasis) const
{
    WidthIterator it(this, run, 0, false, forTextEmphasis);
    GlyphBuffer localGlyphBuffer;
    it.advance(run.length(), &localGlyphBuffer);

    if (localGlyphBuffer.isEmpty())
        return 0;

    float totalWidth = it.m_runWidthSoFar;
    float beforeWidth = 0;
    int glyphPos = 0;
    for (; glyphPos < localGlyphBuffer.size() && it.m_characterIndexOfGlyph[glyphPos] < from; ++glyphPos)
        beforeWidth += localGlyphBuffer.advanceAt(glyphPos).width();
    int glyphFrom = glyphPos;

    float afterWidth = totalWidth;
    glyphPos = localGlyphBuffer.size() - 1;
    for (; glyphPos >= glyphFrom && it.m_characterIndexOfGlyph[glyphPos] >= to; --glyphPos)
        afterWidth -= localGlyphBuffer.advanceAt(glyphPos).width();
    int glyphTo = glyphPos + 1;

    glyphBuffer.add(&localGlyphBuffer, glyphFrom, glyphTo - glyphFrom);

    if (run.rtl()) {
        glyphBuffer.reverse(0, glyphBuffer.size());
        return totalWidth - afterWidth;
    }

    return beforeWidth;
}
Пример #6
0
TEST(GlyphBufferTest, GlyphArrayWithOffset) {
  RefPtr<SimpleFontData> font1 = TestSimpleFontData::create();
  RefPtr<SimpleFontData> font2 = TestSimpleFontData::create();

  GlyphBuffer glyphBuffer;
  glyphBuffer.add(42, font1.get(), 10);
  glyphBuffer.add(43, font1.get(), 15);
  glyphBuffer.add(44, font2.get(), 12);

  EXPECT_FALSE(glyphBuffer.isEmpty());
  EXPECT_EQ(3u, glyphBuffer.size());

  const Glyph* glyphs = glyphBuffer.glyphs(1);
  EXPECT_EQ(43, glyphs[0]);
  EXPECT_EQ(44, glyphs[1]);
}
Пример #7
0
TEST(GlyphBufferTest, StoresSimpleFontData) {
  RefPtr<SimpleFontData> font1 = TestSimpleFontData::create();
  RefPtr<SimpleFontData> font2 = TestSimpleFontData::create();

  GlyphBuffer glyphBuffer;
  glyphBuffer.add(42, font1.get(), 10);
  glyphBuffer.add(43, font1.get(), 15);
  glyphBuffer.add(44, font2.get(), 12);

  EXPECT_FALSE(glyphBuffer.isEmpty());
  EXPECT_EQ(3u, glyphBuffer.size());

  EXPECT_EQ(font1.get(), glyphBuffer.fontDataAt(0));
  EXPECT_EQ(font1.get(), glyphBuffer.fontDataAt(1));
  EXPECT_EQ(font2.get(), glyphBuffer.fontDataAt(2));
}
Пример #8
0
TEST(GlyphBufferTest, StoresGlyphs) {
  RefPtr<SimpleFontData> font1 = TestSimpleFontData::create();
  RefPtr<SimpleFontData> font2 = TestSimpleFontData::create();

  GlyphBuffer glyphBuffer;
  glyphBuffer.add(42, font1.get(), 10);
  glyphBuffer.add(43, font1.get(), 15);
  glyphBuffer.add(44, font2.get(), 22);

  EXPECT_FALSE(glyphBuffer.isEmpty());
  EXPECT_FALSE(glyphBuffer.hasVerticalOffsets());
  EXPECT_EQ(3u, glyphBuffer.size());

  EXPECT_EQ(42, glyphBuffer.glyphAt(0));
  EXPECT_EQ(43, glyphBuffer.glyphAt(1));
  EXPECT_EQ(44, glyphBuffer.glyphAt(2));

  const Glyph* glyphs = glyphBuffer.glyphs(0);
  EXPECT_EQ(42, glyphs[0]);
  EXPECT_EQ(43, glyphs[1]);
  EXPECT_EQ(44, glyphs[2]);
}
Пример #9
0
TEST(GlyphBufferTest, OffsetArrayWithNonZeroIndex) {
  RefPtr<SimpleFontData> font1 = TestSimpleFontData::create();
  RefPtr<SimpleFontData> font2 = TestSimpleFontData::create();

  {
    GlyphBuffer glyphBuffer;
    glyphBuffer.add(42, font1.get(), 10);
    glyphBuffer.add(43, font1.get(), 15);
    glyphBuffer.add(43, font2.get(), 12);

    EXPECT_FALSE(glyphBuffer.isEmpty());
    EXPECT_FALSE(glyphBuffer.hasVerticalOffsets());
    EXPECT_EQ(3u, glyphBuffer.size());

    const float* offsets = glyphBuffer.offsets(1);
    EXPECT_EQ(15, offsets[0]);
    EXPECT_EQ(12, offsets[1]);
  }

  {
    GlyphBuffer glyphBuffer;
    glyphBuffer.add(42, font1.get(), FloatPoint(10, 0));
    glyphBuffer.add(43, font1.get(), FloatPoint(15, 0));
    glyphBuffer.add(43, font2.get(), FloatPoint(12, 2));

    EXPECT_FALSE(glyphBuffer.isEmpty());
    EXPECT_TRUE(glyphBuffer.hasVerticalOffsets());
    EXPECT_EQ(3u, glyphBuffer.size());

    const float* offsets = glyphBuffer.offsets(1);
    EXPECT_EQ(15, offsets[0]);
    EXPECT_EQ(0, offsets[1]);
    EXPECT_EQ(12, offsets[2]);
    EXPECT_EQ(2, offsets[3]);
  }
}
Пример #10
0
void RenderMathMLToken::paint(PaintInfo& info, const LayoutPoint& paintOffset)
{
    RenderMathMLBlock::paint(info, paintOffset);

    // FIXME: Instead of using DrawGlyph, we may consider using the more general TextPainter so that we can apply mathvariant to strings with an arbitrary number of characters and preserve advanced CSS effects (text-shadow, etc).
    if (info.context().paintingDisabled() || info.phase != PaintPhaseForeground || style().visibility() != VISIBLE || !m_mathVariantCodePoint)
        return;

    auto mathVariantGlyph = style().fontCascade().glyphDataForCharacter(m_mathVariantCodePoint.value(), m_mathVariantIsMirrored);
    if (!mathVariantGlyph.font)
        return;

    GraphicsContextStateSaver stateSaver(info.context());
    info.context().setFillColor(style().visitedDependentColor(CSSPropertyColor));

    GlyphBuffer buffer;
    buffer.add(mathVariantGlyph.glyph, mathVariantGlyph.font, mathVariantGlyph.font->widthForGlyph(mathVariantGlyph.glyph));
    LayoutUnit glyphAscent = static_cast<int>(lroundf(-mathVariantGlyph.font->boundsForGlyph(mathVariantGlyph.glyph).y()));
    info.context().drawGlyphs(style().fontCascade(), *mathVariantGlyph.font, buffer, 0, 1, paintOffset + location() + LayoutPoint(0, glyphAscent));
}