// public void CalculateUserCharGlyphAdvancePos(ref TextBufferSpan textBufferSpan, ILineSegmentList lineSegs, RequestFont font, int[] outputUserInputCharAdvance, out int outputTotalW, out int lineHeight) { //layout //from font //resolve for typeface // Typeface typeface = ResolveTypeface(font); _txtServices.SetCurrentFont(typeface, font.SizeInPoints); MyLineSegmentList mylineSegs = (MyLineSegmentList)lineSegs; float scale = typeface.CalculateScaleToPixelFromPointSize(font.SizeInPoints); outputTotalW = 0; int j = mylineSegs.Count; int pos = 0; //start at 0 _reusableTextBuffer.SetRawCharBuffer(textBufferSpan.GetRawCharBuffer()); for (int i = 0; i < j; ++i) { //get each segment MyLineSegment lineSeg = (MyLineSegment)mylineSegs.GetSegment(i); //each line seg may has different script lang _txtServices.CurrentScriptLang = lineSeg.scriptLang; // //CACHING ...., reduce number of GSUB/GPOS // //we cache used line segment for a while //we ask for caching context for a specific typeface and font size GlyphPlanSequence seq = _txtServices.GetUnscaledGlyphPlanSequence(_reusableTextBuffer, lineSeg.StartAt, lineSeg.Length); int seqLen = seq.Count; for (int s = 0; s < seqLen; ++s) { UnscaledGlyphPlan glyphPlan = seq[s]; double actualAdvX = glyphPlan.AdvanceX; outputTotalW += outputUserInputCharAdvance[pos + glyphPlan.input_cp_offset] += (int)Math.Round(actualAdvX * scale); } pos += lineSeg.Length; } // lineHeight = (int)Math.Round(typeface.CalculateRecommendLineSpacing() * scale); _reusableTextBuffer.SetRawCharBuffer(null); }
public Size MeasureString(ref TextBufferSpan textBufferSpan, RequestFont font) { Typeface typeface = ResolveTypeface(font); _txtServices.SetCurrentFont(typeface, font.SizeInPoints); _txtServices.MeasureString(textBufferSpan.GetRawCharBuffer(), textBufferSpan.start, textBufferSpan.len, out int w, out int h); return(new Size(w, h)); }
public void MeasureString(ref TextBufferSpan textBufferSpan, RequestFont font, int limitWidth, out int charFit, out int charFitWidth) { Typeface typeface = ResolveTypeface(font); _txtServices.SetCurrentFont(typeface, font.SizeInPoints); charFit = 0; _txtServices.MeasureString(textBufferSpan.GetRawCharBuffer(), textBufferSpan.start, textBufferSpan.len, limitWidth, out charFit, out charFitWidth); }
public GlyphPlanSequence CreateGlyphPlanSeq(ref TextBufferSpan textBufferSpan, RequestFont font) { Typeface typeface = ResolveTypeface(font); _txtServices.SetCurrentFont(typeface, font.SizeInPoints); _reusableTextBuffer.SetRawCharBuffer(textBufferSpan.GetRawCharBuffer()); return(_txtServices.GetUnscaledGlyphPlanSequence(_reusableTextBuffer, textBufferSpan.start, textBufferSpan.len)); }
public ILineSegmentList BreakToLineSegments(ref TextBufferSpan textBufferSpan) { //a text buffer span is separated into multiple line segment list char[] str = textBufferSpan.GetRawCharBuffer(); int cur_startAt = textBufferSpan.start; MyLineSegmentList lineSegments = MyLineSegmentList.GetFreeLineSegmentList(); foreach (BreakSpan breakSpan in _txtServices.BreakToLineSegments(str, textBufferSpan.start, textBufferSpan.len)) { MyLineSegment lineSeg = new MyLineSegment(lineSegments, breakSpan.startAt, breakSpan.len); lineSeg.scriptLang = breakSpan.scLang; lineSegments.AddLineSegment(lineSeg); } return(lineSegments); }
public ILineSegmentList BreakToLineSegments(ref TextBufferSpan textBufferSpan) { _resuableLineSegments.Clear(); //a text buffer span is separated into multiple line segment list char[] str = textBufferSpan.GetRawCharBuffer(); MyLineSegmentList lineSegs = new MyLineSegmentList(textBufferSpan.start, textBufferSpan.len); int cur_startAt = textBufferSpan.start; foreach (BreakSpan breakSpan in _txtServices.BreakToLineSegments(str, textBufferSpan.start, textBufferSpan.len)) { MyLineSegment lineSeg = new MyLineSegment(lineSegs, breakSpan.startAt, breakSpan.len); lineSeg.scriptLang = breakSpan.scLang; _resuableLineSegments.Add(lineSeg); } //TODO: review here, //check if we need to create new array everytime? lineSegs.SetResultLineSegments(_resuableLineSegments.ToArray()); _resuableLineSegments.Clear(); return(lineSegs); }
public void CalculateUserCharGlyphAdvancePos(ref TextBufferSpan textBufferSpan, ILineSegmentList lineSegs, RequestFont font, int[] outputUserInputCharAdvance, out int outputTotalW, out int lineHeight) { //layout //from font //resolve for typeface // Typeface typeface = ResolveTypeface(font); _txtServices.SetCurrentFont(typeface, font.SizeInPoints); MyLineSegmentList mylineSegs = (MyLineSegmentList)lineSegs; float scale = typeface.CalculateScaleToPixelFromPointSize(font.SizeInPoints); outputTotalW = 0; int j = mylineSegs.Count; int pos = 0; //start at 0 _reusableTextBuffer.SetRawCharBuffer(textBufferSpan.GetRawCharBuffer()); for (int i = 0; i < j; ++i) { //userGlyphPlanList.Clear(); //userCharToGlyphMapList.Clear(); //get each segment MyLineSegment lineSeg = mylineSegs.GetSegment(i); //each line seg may has different script lang _txtServices.CurrentScriptLang = lineSeg.scriptLang; // //CACHING ...., reduce number of GSUB/GPOS // //we cache used line segment for a while //we ask for caching context for a specific typeface and font size GlyphPlanSequence seq = _txtServices.GetUnscaledGlyphPlanSequence(_reusableTextBuffer, lineSeg.StartAt, lineSeg.Length); //IMPORTANT //num of glyph may more or less than original user input char buffer // //float g_x = 0; //float g_y = 0; //int baseY = (int)Math.Round(y); //int n = glyphPlanSeq.len; //int endBefore = glyphPlanSeq.startAt + n; ////*** //_glsx.SetAssociatedTextureInfo(_glBmp); //List<float> vboBufferList = new List<float>(); //List<ushort> indexList = new List<ushort>(); //for (int i = glyphPlanSeq.startAt; i < endBefore; ++i) //{ // GlyphPlanList glyphPlanList = GlyphPlanSequence.UnsafeGetInteralGlyphPlanList(glyphPlanSeq); // GlyphPlan glyph = glyphPlanList[i]; // Typography.Rendering.TextureGlyphMapData glyphData; // if (!_fontAtlas.TryGetGlyphDataByCodePoint(glyph.glyphIndex, out glyphData)) // { // //if no glyph data, we should render a missing glyph *** // continue; // } // //if (scaleFromTexture != 1) // //{ // //} // //-------------------------------------- // //TODO: review precise height in float // //-------------------------------------- // PixelFarm.Drawing.Rectangle srcRect = ConvToRect(glyphData.Rect); // g_x = (float)(x + (glyph.ExactX * scale - glyphData.TextureXOffset) * scaleFromTexture); //ideal x // g_y = (float)(y + (glyph.ExactY * scale - glyphData.TextureYOffset + srcRect.Height) * scaleFromTexture); // //for sharp glyph // //we adjust g_x,g_y to integer value // //float g_y2 = (float)Math.Floor(g_y); // g_x = (float)Math.Round(g_x); // g_y = (float)Math.Floor(g_y); // switch (textureKind) // { // case TextureKind.Msdf: // _glsx.DrawSubImageWithMsdf(_glBmp, // ref srcRect, // g_x, // g_y, // scaleFromTexture); // break; // case TextureKind.StencilGreyScale: // //stencil gray scale with fill-color // _glsx.DrawGlyphImageWithStecil(_glBmp, // ref srcRect, // g_x, // g_y, // scaleFromTexture); // break; // case TextureKind.Bitmap: // _glsx.DrawSubImage(_glBmp, // ref srcRect, // g_x, // g_y, // scaleFromTexture); // break; // case TextureKind.StencilLcdEffect: // _glsx.WriteVboToList( // vboBufferList, // indexList, // ref srcRect, // g_x, // g_y, // scaleFromTexture); // break; // } //} ////--------- int seqLen = seq.Count; for (int s = 0; s < seqLen; ++s) { UnscaledGlyphPlan glyphPlan = seq[s]; double actualAdvX = glyphPlan.AdvanceX; outputTotalW += outputUserInputCharAdvance[pos + glyphPlan.input_cp_offset] += (int)Math.Round(actualAdvX * scale); } pos += lineSeg.Length; } // lineHeight = (int)Math.Round(typeface.CalculateRecommendLineSpacing() * scale); _reusableTextBuffer.SetRawCharBuffer(null); }
public void CalculateUserCharGlyphAdvancePos(ref TextBufferSpan textBufferSpan, ILineSegmentList lineSegs, RequestFont font, int[] outputUserInputCharAdvance, out int outputTotalW, out int lineHeight) { //layout //from font //resolve for typeface // Typeface typeface = ResolveTypeface(font); _typographyTxtServices.SetCurrentFont(typeface, font.SizeInPoints); MyLineSegmentList mylineSegs = (MyLineSegmentList)lineSegs; float scale = typeface.CalculateScaleToPixelFromPointSize(font.SizeInPoints); outputTotalW = 0; int j = mylineSegs.Count; int pos = 0; //start at 0 _reusableTextBuffer.SetRawCharBuffer(textBufferSpan.GetRawCharBuffer()); for (int i = 0; i < j; ++i) { //userGlyphPlanList.Clear(); //userCharToGlyphMapList.Clear(); //get each segment MyLineSegment lineSeg = mylineSegs.GetSegment(i); //each line seg may has different script lang _typographyTxtServices.CurrentScriptLang = lineSeg.scriptLang; // //CACHING ...., reduce number of GSUB/GPOS // //we cache used line segment for a while //we ask for caching context for a specific typeface and font size GlyphPlanSequence seq = _typographyTxtServices.GetUnscaledGlyphPlanSequence(_reusableTextBuffer, lineSeg.StartAt, lineSeg.Length); GlyphPlanList planList = GlyphPlanSequence.UnsafeGetInteralGlyphPlanList(seq); //IMPORTANT //num of glyph may more or less than original user input char buffer // int endAt = seq.startAt + seq.len; int seq_startAt = seq.startAt; for (int s = seq_startAt; s < endAt; ++s) { GlyphPlan glyphPlan = planList[s]; float tx = glyphPlan.ExactX; float ty = glyphPlan.ExactY; double actualAdvX = glyphPlan.AdvanceX; outputTotalW += outputUserInputCharAdvance[pos + glyphPlan.input_cp_offset] += (int)Math.Round(actualAdvX * scale); } pos += lineSeg.Length; } // lineHeight = (int)Math.Round(typeface.CalculateRecommendLineSpacing() * scale); _reusableTextBuffer.SetRawCharBuffer(null); }
public void MeasureString(ref TextBufferSpan textBufferSpan, RequestFont font, int maxWidth, out int charFit, out int charFitWidth) { WinGdiTextService.MeasureString(textBufferSpan.GetRawCharBuffer(), textBufferSpan.start, textBufferSpan.len, font, maxWidth, out charFit, out charFitWidth); }
public PixelFarm.Drawing.Size MeasureString(ref TextBufferSpan textBufferSpan, RequestFont font) { return(WinGdiTextService.MeasureString(textBufferSpan.GetRawCharBuffer(), textBufferSpan.start, textBufferSpan.len, font)); }
//============================================== public static void CalculateGlyphAdvancePos(ref TextBufferSpan textBufferSpan, RequestFont font, int[] outputGlyphAdvances, out int outputTotalW) { unsafe { outputTotalW = 0; int len = textBufferSpan.len; if (len == 0) { return; } WinGdiFont winfont = SetFont(font); //ushort* glyhIndics = stackalloc ushort[len]; //fixed (char* s = &str[startAt]) //{ // NativeTextWin32.GetGlyphIndices( // win32MemDc.DC, // s, // len, // glyhIndics, // 0); //} byte[] encoding = s_en.GetBytes( textBufferSpan.GetRawCharBuffer(), textBufferSpan.start, len); NativeTextWin32.FontABC[] abcWidths = winfont.GetInteralABCArray(); int totalW = 0; for (int i = 0; i < len; ++i) { //ushort glyphIndex = *(glyhIndics + i); int enc_index = encoding[i]; if (enc_index == 0) { break;//? } totalW += outputGlyphAdvances[i] = abcWidths[enc_index].Sum; } } //unsafe //{ // SetFont(font); // NativeTextWin32.GCP_RESULTS gpcResult = new NativeTextWin32.GCP_RESULTS(); // int[] caretpos = new int[len]; // uint[] lpOrder = new uint[len]; // int[] lpDx = new int[len]; // fixed (int* lpdx_h = &lpDx[0]) // fixed (uint* lpOrder_h = &lpOrder[0]) // fixed (int* caretpos_h = &caretpos[0]) // fixed (char* str_h = &str[startAt]) // { // gpcResult.lpCaretPos = caretpos_h; // gpcResult.lpOrder = lpOrder_h; // gpcResult.lpDx = lpdx_h; // //gpcResult. // ////gpcResult.lpCaretPos = // NativeTextWin32.GetCharacterPlacement( // win32MemDc.DC, // str_h, // len, // len, ref gpcResult, 0); // } //} }