/****************************************************************************** * ME_PointFromCharContext * * Returns a run-relative pixel position given a run-relative character * position (character offset) */ int ME_PointFromCharContext(ME_Context *c, ME_Run *pRun, int nOffset, BOOL visual_order) { SIZE size; ME_String *mask_text = NULL; WCHAR *str; if (pRun->nFlags & MERF_GRAPHICS) { if (nOffset) ME_GetOLEObjectSize(c, pRun, &size); return nOffset != 0; } else if (pRun->nFlags & MERF_ENDPARA) { nOffset = 0; } if (pRun->para->nFlags & MEPF_COMPLEX) { int x; ScriptCPtoX( nOffset, FALSE, pRun->len, pRun->num_glyphs, pRun->clusters, pRun->vis_attrs, pRun->advances, &pRun->script_analysis, &x ); if (visual_order && pRun->script_analysis.fRTL) x = pRun->nWidth - x - 1; return x; } if (c->editor->cPasswordMask) { mask_text = ME_MakeStringR(c->editor->cPasswordMask, pRun->len); str = mask_text->szData; } else str = get_text( pRun, 0 ); ME_GetTextExtent(c, str, nOffset, pRun->style, &size); ME_DestroyString( mask_text ); return size.cx; }
int UniscribeHelper::characterToX(int offset) const { HRESULT hr; ASSERT(offset <= m_inputLength); // Our algorithm is to traverse the items in screen order from left to // right, adding in each item's screen width until we find the item with // the requested character in it. int width = 0; for (size_t screenIndex = 0; screenIndex < m_runs.size(); screenIndex++) { // Compute the length of this run. int itemIndex = m_screenOrder[screenIndex]; const SCRIPT_ITEM& item = m_runs[itemIndex]; const Shaping& shaping = m_shapes[itemIndex]; int itemLength = shaping.charLength(); if (offset >= item.iCharPos && offset <= item.iCharPos + itemLength) { // Character offset is in this run. int charLength = offset - item.iCharPos; int curX = 0; hr = ScriptCPtoX(charLength, FALSE, itemLength, shaping.glyphLength(), &shaping.m_logs[0], &shaping.m_visualAttributes[0], shaping.effectiveAdvances(), &item.a, &curX); if (FAILED(hr)) return 0; width += curX + shaping.m_prePadding; ASSERT(width >= 0); return width; } // Move to the next item. width += advanceForItem(itemIndex); } ASSERT(width >= 0); return width; }