void UniscribeController::itemizeShapeAndPlace(const UChar* cp, unsigned length, const Font* fontData, GlyphBuffer* glyphBuffer) { // ScriptItemize (in Windows XP versions prior to SP2) can overflow by 1. This is why there is an extra empty item // hanging out at the end of the array m_items.resize(6); int numItems = 0; HRESULT rc = S_OK; while (rc = ::ScriptItemize(cp, length, m_items.size() - 1, &m_control, &m_state, m_items.data(), &numItems) == E_OUTOFMEMORY) { m_items.resize(m_items.size() * 2); resetControlAndState(); } if (FAILED(rc)) { WTFLogAlways("UniscribeController::itemizeShapeAndPlace: ScriptItemize failed, rc=%lx", rc); return; } m_items.resize(numItems + 1); if (m_run.rtl()) { for (int i = m_items.size() - 2; i >= 0; i--) { if (!shapeAndPlaceItem(cp, i, fontData, glyphBuffer)) return; } } else { for (unsigned i = 0; i < m_items.size() - 1; i++) { if (!shapeAndPlaceItem(cp, i, fontData, glyphBuffer)) return; } } }
// FIXME: Rearchitect this to be more like WidthIterator in Font.cpp. Have an advance() method // that does stuff in that method instead of doing everything in the constructor. Have advance() // take the GlyphBuffer as an arg so that we don't have to populate the glyph buffer when // measuring. UniscribeController::UniscribeController(const Font* font, const TextRun& run, HashSet<const SimpleFontData*>* fallbackFonts) : m_font(*font) , m_run(run) , m_fallbackFonts(fallbackFonts) , m_minGlyphBoundingBoxX(numeric_limits<float>::max()) , m_maxGlyphBoundingBoxX(numeric_limits<float>::min()) , m_minGlyphBoundingBoxY(numeric_limits<float>::max()) , m_maxGlyphBoundingBoxY(numeric_limits<float>::min()) , m_end(run.length()) , m_currentCharacter(0) , m_runWidthSoFar(0) , m_padding(run.expansion()) , m_computingOffsetPosition(false) , m_includePartialGlyphs(false) , m_offsetX(0) , m_offsetPosition(0) { if (!m_padding) m_padPerSpace = 0; else { float numSpaces = 0; for (int s = 0; s < m_run.length(); s++) { if (Font::treatAsSpace(m_run[s])) numSpaces++; } if (numSpaces == 0) m_padPerSpace = 0; else m_padPerSpace = m_padding / numSpaces; } // Null out our uniscribe structs resetControlAndState(); }
// FIXME: Rearchitect this to be more like WidthIterator in Font.cpp. Have an advance() method // that does stuff in that method instead of doing everything in the constructor. Have advance() // take the GlyphBuffer as an arg so that we don't have to populate the glyph buffer when // measuring. UniscribeController::UniscribeController(const Font* font, const TextRun& run, HashSet<const SimpleFontData*>* fallbackFonts) : m_font(*font) , m_run(run) , m_fallbackFonts(fallbackFonts) , m_end(run.length()) , m_currentCharacter(0) , m_runWidthSoFar(0) , m_computingOffsetPosition(false) , m_includePartialGlyphs(false) , m_offsetX(0) , m_offsetPosition(0) { m_padding = m_run.padding(); if (!m_padding) m_padPerSpace = 0; else { float numSpaces = 0; for (int s = 0; s < m_run.length(); s++) if (Font::treatAsSpace(m_run[s])) numSpaces++; if (numSpaces == 0) m_padPerSpace = 0; else m_padPerSpace = ceilf(m_run.padding() / numSpaces); } // Null out our uniscribe structs resetControlAndState(); }