/*---------------------------------------------------------------------------------------------- Return the ISO-639-3 language code, cast to an unsigned int. ----------------------------------------------------------------------------------------------*/ isocode FwGrTxtSrc::getLanguage(toffset ich) { LgCharRenderProps lgchrp; int ichMinBogus, ichLimBogus; GrResult res = (GrResult)m_qts->GetCharProps(GrToVwOffset(ich), &lgchrp, &ichMinBogus, &ichLimBogus); int ws = lgchrp.ws; ILgWritingSystemFactoryPtr qwsf; ILgWritingSystemPtr qws; CheckHr(m_qts->GetWsFactory(&qwsf)); AssertPtr(qwsf); CheckHr(qwsf->get_EngineOrNull(ws, &qws)); isocode code; if (!qws) { memset(code.rgch, 0, sizeof(char) * 4); return code; } SmartBstr bstrLang; CheckHr(qws->get_ISO3(&bstrLang)); for (int i = 0; i < 4; i++) code.rgch[i] = (char)(i >= bstrLang.Length() ? 0 : bstrLang[i]); return code; }
/*---------------------------------------------------------------------------------------------- Return the ISO-639-3 language code, cast to an unsigned int. ----------------------------------------------------------------------------------------------*/ isocode FwGrTxtSrc::getLanguage(toffset ich) { LgCharRenderProps lgchrp; int ichMinBogus, ichLimBogus; GrResult res = (GrResult)m_qts->GetCharProps(GrToVwOffset(ich), &lgchrp, &ichMinBogus, &ichLimBogus); int ws = lgchrp.ws; ILgWritingSystemFactoryPtr qwsf; IWritingSystemPtr qws; CheckHr(m_qts->GetWsFactory(&qwsf)); if (qwsf) { CheckHr(qwsf->get_EngineOrNull(ws, &qws)); } else { qwsf.CreateInstance(CLSID_LgWritingSystemFactory); // Get the memory-based factory. CheckHr(qwsf->get_EngineOrNull(ws, &qws)); } isocode code; if (!qws) { memset(code.rgch, 0, sizeof(char) * 4); return code; } SmartBstr bstrLang, bstrScript, bstrCountry, bstrVariant; CheckHr(qws->GetIcuLocaleParts(&bstrLang, &bstrScript, &bstrCountry, &bstrVariant)); for (int i = 0; i < 4; i++) code.rgch[i] = (char)(i >= bstrLang.Length() ? 0 : bstrLang[i]); return code; }
/*---------------------------------------------------------------------------------------------- Return true if the text uses a right-to-left writing system. ----------------------------------------------------------------------------------------------*/ unsigned int FwGrTxtSrc::getDirectionDepth(toffset ich) { LgCharRenderProps lgchrp; int ichMinBogus, ichLimBogus; GrResult res = (GrResult)m_qts->GetCharProps(GrToVwOffset(ich), &lgchrp, &ichMinBogus, &ichLimBogus); return lgchrp.nDirDepth; }
/*---------------------------------------------------------------------------------------------- Return true if the text uses a right-to-left writing system. ----------------------------------------------------------------------------------------------*/ bool FwGrTxtSrc::getRightToLeft(toffset ich) { LgCharRenderProps lgchrp; int ichMinBogus, ichLimBogus; GrResult res = (GrResult)m_qts->GetCharProps(GrToVwOffset(ich), &lgchrp, &ichMinBogus, &ichLimBogus); return lgchrp.fWsRtl; }
/*---------------------------------------------------------------------------------------------- Temporary--eventually these will be of interest only to SegmentPainter. ----------------------------------------------------------------------------------------------*/ void FwGrTxtSrc::getColors(toffset ich, int * pclrFore, int * pclrBack) { LgCharRenderProps lgchrp; int ichMinBogus, ichLimBogus; GrResult res = (GrResult)m_qts->GetCharProps(GrToVwOffset(ich), &lgchrp, &ichMinBogus, &ichLimBogus); *pclrFore = (int)lgchrp.clrFore; *pclrBack = (int)lgchrp.clrBack; }
/*---------------------------------------------------------------------------------------------- Return true if the two characters represent runs that can be rendered in the same segment. ----------------------------------------------------------------------------------------------*/ bool FwGrTxtSrc::sameSegment(toffset ich1, toffset ich2) { int ichMinBogus, ichLimBogus; LgCharRenderProps chrp1, chrp2; GrResult res = (GrResult)m_qts->GetCharProps(GrToVwOffset(ich1), &chrp1, &ichMinBogus, &ichLimBogus); if (ResultFailed(res)) return false; res = (GrResult)m_qts->GetCharProps(GrToVwOffset(ich2), &chrp2, &ichMinBogus, &ichLimBogus); if (ResultFailed(res)) return false; if (u_strcmp(chrp1.szFaceName, chrp2.szFaceName) != 0) return false; if (chrp1.ws != chrp2.ws) { // Can't compare default fonts for different writing systems. StrUni stuFace; stuFace.Assign(chrp1.szFaceName, 8); if (stuFace == L"<default") return false; } if (chrp1.dympHeight != chrp2.dympHeight) return false; if (chrp1.ttvBold != chrp2.ttvBold) return false; if (chrp1.ttvItalic != chrp2.ttvItalic) return false; if (chrp1.fWsRtl != chrp2.fWsRtl) return false; if (chrp1.nDirDepth != chrp2.nDirDepth) return false; if (chrp1.ssv != chrp2.ssv) return false; if (chrp1.dympOffset != chrp2.dympOffset) return false; // eventually improve on this return true; }
/*---------------------------------------------------------------------------------------------- Return a list of font feature settings for the given character. ----------------------------------------------------------------------------------------------*/ size_t FwGrTxtSrc::getFontFeatures(toffset ich, FeatureSetting * prgfset) { int ichMinBogus, ichLimBogus; int cfset = 0; int vwIch = GrToVwOffset(ich); // The first batch of features comes from the style setting. LgCharRenderProps lgchrp; GrResult res = (GrResult)m_qts->GetCharProps(vwIch, &lgchrp, &ichMinBogus, &ichLimBogus); if (ResultFailed(res)) return cfset; #if WIN32 std::wstring stuFromStyle(lgchrp.szFontVar); #else std::wstring stuFromStyle = StrUtil::wstring(lgchrp.szFontVar); #endif ParseFeatureString(stuFromStyle, kMaxFeatures, prgfset, &cfset); // The second batch comes from the hard-formatting on the text. // Because of the way the strings are stored this step is probably not necessary // (the first string is a superset of the second), but just to be on the safe side... SmartBstr sbstrString; res = (GrResult)m_qts->GetCharStringProp(vwIch, ktptFontVariations, &sbstrString, &ichMinBogus, &ichLimBogus); if (ResultFailed(res)) return cfset; if (sbstrString) { std::wstring stuFromString(sbstrString); if (stuFromString != stuFromStyle) ParseFeatureString(stuFromString, kMaxFeatures, prgfset, &cfset); } Assert(cfset < kMaxFeatures); // otherwise memory has been clobbered //for (int ifeat = 0; ifeat < min(*pcfset, cMax); ifeat++) //{ // prgfset[ifeat].id = rgFeatIDs[ifeat]; // prgfset[ifeat].value = rgValues[ifeat]; //} return cfset; }
/*---------------------------------------------------------------------------------------------- Return the size of the text, in points. ----------------------------------------------------------------------------------------------*/ float FwGrTxtSrc::getVerticalOffset(toffset ich) { LgCharRenderProps lgchrp; int ichMinBogus, ichLimBogus; GrResult res = (GrResult)m_qts->GetCharProps(GrToVwOffset(ich), &lgchrp, &ichMinBogus, &ichLimBogus); int dympOffset = lgchrp.dympOffset; if(lgchrp.ssv != kssvOff) { // psuedo device context works since we are getting proportions which are invariant HDC hdc = ::CreateDC(TEXT("DISPLAY"),NULL,NULL,NULL); IVwGraphicsWin32Ptr qvgW; qvgW.CreateInstance(CLSID_VwGraphicsWin32); qvgW->Initialize(hdc); IVwGraphicsPtr qvg; CheckHr(qvgW->QueryInterface(IID_IVwGraphics, (void **) &qvg)); CheckHr(qvg->SetupGraphics(&lgchrp)); if (lgchrp.ssv == kssvSuper) { int dSuperscriptYOffsetNumerator; int dSuperscriptYOffsetDenominator; CheckHr(qvg->GetSuperscriptYOffsetRatio(&dSuperscriptYOffsetNumerator, &dSuperscriptYOffsetDenominator)); dympOffset += gr::GrEngine::GrIntMulDiv(lgchrp.dympHeight, dSuperscriptYOffsetNumerator, dSuperscriptYOffsetDenominator); } else if (lgchrp.ssv == kssvSub) { int dSubscriptYOffsetNumerator; int dSubscriptYOffsetDenominator; CheckHr(qvg->GetSubscriptYOffsetRatio(&dSubscriptYOffsetNumerator, &dSubscriptYOffsetDenominator)); dympOffset -= gr::GrEngine::GrIntMulDiv(lgchrp.dympHeight, dSubscriptYOffsetNumerator, dSubscriptYOffsetDenominator); } qvgW.Clear(); qvg.Clear(); ::DeleteDC(hdc); } return (float)(dympOffset / 1000); }
/*---------------------------------------------------------------------------------------------- Return the indices of a range of characters that all share the same properties. ----------------------------------------------------------------------------------------------*/ std::pair<toffset, toffset> FwGrTxtSrc::propertyRange(toffset ich) { LgCharRenderProps lgchrp; int ichMin, ichLim; GrResult res = (GrResult)m_qts->GetCharProps(GrToVwOffset(ich), &lgchrp, &ichMin, &ichLim); // for testing UTF-8: //if (ichMin != 0) //{ // Assert(false); //} //gr::utf16 prgchw[1000]; //fetch(0, ichLim, prgchw); //ichLim = CountUtf8FromUtf16(prgchw, *pichLim); //////////////////// std::pair<toffset, toffset> pairRet; pairRet.first = VwToGrOffset(ichMin); pairRet.second = VwToGrOffset(ichLim); return pairRet; }
DEFINE_THIS_FILE //:>******************************************************************************************** //:> FwGrTxtSrc //:>******************************************************************************************** size_t FwGrTxtSrc::fetch(toffset ichMin, size_t cch, gr::utf16 * prgchwBuffer) { HRESULT hr; int cchLen; IgnoreHr(hr = (gr::GrResult)m_qts->get_Length(&cchLen)); if (FAILED(hr)) throw; if (!m_useNFC) { int cchGet = min(cch, cchLen - ichMin); IgnoreHr(hr = (gr::GrResult)m_qts->Fetch(ichMin, ichMin + cchGet, (OLECHAR*)prgchwBuffer)); if (FAILED(hr)) throw; return cchGet; } else { int vwIchMin = GrToVwOffset(ichMin); int len = cchLen - vwIchMin; wchar_t* pchNfd; StrUni stuText; stuText.SetSize(len + 1, &pchNfd); IgnoreHr(hr = (gr::GrResult)m_qts->Fetch(vwIchMin, vwIchMin + len, pchNfd)); if (FAILED(hr)) throw; pchNfd[len] = '\0'; stuText.SetSize(len, &pchNfd); StrUtil::NormalizeStrUni(stuText, UNORM_NFC); int cchGet = min((int) cch, stuText.Length()); wcsncpy((wchar_t*) prgchwBuffer, stuText.Chars(), cchGet); return cchGet; } }