public static int stbtt_PackFontRanges(stbtt_pack_context spc, byte *fontdata, int font_index, stbtt_pack_range *ranges, int num_ranges) { stbtt_fontinfo info = new stbtt_fontinfo(); int i = 0; int j = 0; int n = 0; int return_value = (int)(1); stbrp_rect * rects; for (i = (int)(0); (i) < (num_ranges); ++i) { for (j = (int)(0); (j) < (ranges[i].num_chars); ++j) { ranges[i].chardata_for_range[j].x0 = (ushort)(ranges[i].chardata_for_range[j].y0 = (ushort)(ranges[i].chardata_for_range[j].x1 = (ushort)(ranges[i].chardata_for_range[j].y1 = (ushort)(0)))); } } n = (int)(0); for (i = (int)(0); (i) < (num_ranges); ++i) { n += (int)(ranges[i].num_chars); } rects = (stbrp_rect *)(CRuntime.malloc((ulong)(sizeof(stbrp_rect) * n))); if ((rects) == (null)) { return((int)(0)); } info.userdata = spc.user_allocator_context; stbtt_InitFont(info, fontdata, (int)(stbtt_GetFontOffsetForIndex(fontdata, (int)(font_index)))); n = (int)(stbtt_PackFontRangesGatherRects(spc, info, ranges, (int)(num_ranges), rects)); stbtt_PackFontRangesPackRects(spc, rects, (int)(n)); return_value = (int)(stbtt_PackFontRangesRenderIntoRects(spc, info, ranges, (int)(num_ranges), rects)); CRuntime.free(rects); return((int)(return_value)); }
public static void stbtt_GetGlyphBitmapBox(stbtt_fontinfo font, int glyph, float scale_x, float scale_y, ref int x0, ref int y0, ref int x1, ref int y1) { var px0 = new FakePtr <int>(1) { Value = x0 }; var px1 = new FakePtr <int>(1) { Value = x1 }; var py0 = new FakePtr <int>(1) { Value = y0 }; var py1 = new FakePtr <int>(1) { Value = y1 }; stbtt_GetGlyphBitmapBox(font, glyph, scale_x, scale_y, px0, py0, px1, py1); x0 = px0.Value; x1 = px1.Value; y0 = py0.Value; y1 = py1.Value; }
/// <summary> /// Loads a font from a block of bytes. /// </summary> public Font(byte[] file) { // Keep file around in memory, since the native points directly to it. // We will clone the data using unmanaged memory (🙊) _inMemoryFile = CloneUnmanaged(file); Info = new stbtt_fontinfo(); // Initialize the font, populating the stb info structure if (stbtt_InitFont(Info, _inMemoryFile, 0) == 0) { throw new InvalidOperationException("Unable to load font"); } // Extract vertical metrics (at raw scale) int ascent, descent, lineGap; stbtt_GetFontVMetrics(Info, &ascent, &descent, &lineGap); // Store raw face metrics _ascent = ascent; _descent = descent; _lineGap = lineGap; // _glyphLookup = new Dictionary <UnicodeCharacter, Glyph>(); _glyphs = new Glyph[Info.numGlyphs]; }
public static int stbtt_GetGlyphBox(stbtt_fontinfo info, int glyph_index, ref int x0, ref int y0, ref int x1, ref int y1) { var px0 = new FakePtr <int>(1) { Value = x0 }; var px1 = new FakePtr <int>(1) { Value = x1 }; var py0 = new FakePtr <int>(1) { Value = y0 }; var py1 = new FakePtr <int>(1) { Value = y1 }; var result = stbtt_GetGlyphBox(info, glyph_index, px0, py0, px1, py1); x0 = px0.Value; x1 = px1.Value; y0 = py0.Value; y1 = py1.Value; return(result); }
protected virtual void Dispose(bool disposing) { if (disposing && _font != null) { _font.Dispose(); _font = null; } }
public static int stbtt_BakeFontBitmap_internal(byte *data, int offset, float pixel_height, byte *pixels, int pw, int ph, int first_char, int num_chars, stbtt_bakedchar *chardata) { float scale = 0; int x = 0; int y = 0; int bottom_y = 0; int i = 0; stbtt_fontinfo f = new stbtt_fontinfo(); f.userdata = (null); if (stbtt_InitFont(f, data, (int)(offset)) == 0) { return((int)(-1)); } CRuntime.memset(pixels, (int)(0), (ulong)(pw * ph)); x = (int)(y = (int)(1)); bottom_y = (int)(1); scale = (float)(stbtt_ScaleForPixelHeight(f, (float)(pixel_height))); for (i = (int)(0); (i) < (num_chars); ++i) { int advance = 0; int lsb = 0; int x0 = 0; int y0 = 0; int x1 = 0; int y1 = 0; int gw = 0; int gh = 0; int g = (int)(stbtt_FindGlyphIndex(f, (int)(first_char + i))); stbtt_GetGlyphHMetrics(f, (int)(g), &advance, &lsb); stbtt_GetGlyphBitmapBox(f, (int)(g), (float)(scale), (float)(scale), &x0, &y0, &x1, &y1); gw = (int)(x1 - x0); gh = (int)(y1 - y0); if ((x + gw + 1) >= (pw)) { y = (int)(bottom_y); x = (int)(1); } if ((y + gh + 1) >= (ph)) { return((int)(-i)); } stbtt_MakeGlyphBitmap(f, pixels + x + y * pw, (int)(gw), (int)(gh), (int)(pw), (float)(scale), (float)(scale), (int)(g)); chardata[i].x0 = (ushort)((short)(x)); chardata[i].y0 = (ushort)((short)(y)); chardata[i].x1 = (ushort)((short)(x + gw)); chardata[i].y1 = (ushort)((short)(y + gh)); chardata[i].xadvance = (float)(scale * advance); chardata[i].xoff = ((float)(x0)); chardata[i].yoff = ((float)(y0)); x = (int)(x + gw + 1); if ((y + gh + 1) > (bottom_y)) { bottom_y = (int)(y + gh + 1); } } return((int)(bottom_y)); }
public static int stbtt_BakeFontBitmap_internal(byte *data, int offset, float pixel_height, byte *pixels, int pw, int ph, int first_char, int num_chars, stbtt_bakedchar *chardata) { float scale = 0; int x = 0; int y = 0; int bottom_y = 0; int i = 0; stbtt_fontinfo f = new stbtt_fontinfo(); f.userdata = (null); if (stbtt_InitFont(f, data, offset) == 0) { return(-1); } CRuntime.Memset(pixels, 0, (ulong)(pw * ph)); x = y = 1; bottom_y = 1; scale = stbtt_ScaleForPixelHeight(f, pixel_height); for (i = 0; (i) < (num_chars); ++i) { int advance = 0; int lsb = 0; int x0 = 0; int y0 = 0; int x1 = 0; int y1 = 0; int gw = 0; int gh = 0; int g = stbtt_FindGlyphIndex(f, first_char + i); stbtt_GetGlyphHMetrics(f, g, &advance, &lsb); stbtt_GetGlyphBitmapBox(f, g, scale, scale, &x0, &y0, &x1, &y1); gw = x1 - x0; gh = y1 - y0; if ((x + gw + 1) >= (pw)) { y = bottom_y; x = 1; } if ((y + gh + 1) >= (ph)) { return(-i); } stbtt_MakeGlyphBitmap(f, pixels + x + y * pw, gw, gh, pw, scale, scale, g); chardata[i].x0 = (ushort)((short)(x)); chardata[i].y0 = (ushort)((short)(y)); chardata[i].x1 = (ushort)((short)(x + gw)); chardata[i].y1 = (ushort)((short)(y + gh)); chardata[i].xadvance = scale * advance; chardata[i].xoff = x0; chardata[i].yoff = y0; x = x + gw + 1; if ((y + gh + 1) > (bottom_y)) { bottom_y = y + gh + 1; } } return(bottom_y); }
private void Initialize(byte[] ttf) { byte *bytePtr = (byte *)GCHandle.Alloc(ttf, GCHandleType.Pinned).AddrOfPinnedObject(); font = new stbtt_fontinfo(); stbtt_InitFont(font, bytePtr, 0); HaveGlyph(int.MaxValue); GC.Collect(); }
private void Initialize(GraphicsDevice graphicsDevice, byte[] ttf) { this.graphicsDevice = graphicsDevice; byte *bytePtr = (byte *)GCHandle.Alloc(ttf, GCHandleType.Pinned).AddrOfPinnedObject(); font = new stbtt_fontinfo(); stbtt_InitFont(font, bytePtr, 0); GC.Collect(); }
/// <inheritdoc/> protected virtual void Dispose(bool disposeManaged) { if (!_isDisposed) { if (disposeManaged) { Info = default; } // Free font file clone on heap Marshal.FreeHGlobal((IntPtr)_inMemoryFile); _isDisposed = true; } }
public static void stbtt_GetScaledFontVMetrics(byte *fontdata, int index, float size, float *ascent, float *descent, float *lineGap) { int i_ascent = 0; int i_descent = 0; int i_lineGap = 0; float scale = 0; stbtt_fontinfo info = new stbtt_fontinfo(); stbtt_InitFont(info, fontdata, stbtt_GetFontOffsetForIndex(fontdata, index)); scale = (size) > (0) ? stbtt_ScaleForPixelHeight(info, size) : stbtt_ScaleForMappingEmToPixels(info, -size); stbtt_GetFontVMetrics(info, &i_ascent, &i_descent, &i_lineGap); *ascent = i_ascent * scale; *descent = i_descent * scale; *lineGap = i_lineGap * scale; }
public static int stbtt_PackFontRangesGatherRects(stbtt_pack_context spc, stbtt_fontinfo info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects) { var i = 0; var j = 0; var k = 0; var missing_glyph_added = 0; k = 0; for (i = 0; i < num_ranges; ++i) { var fh = ranges[i].font_size; var scale = fh > 0 ? stbtt_ScaleForPixelHeight(info, fh) : stbtt_ScaleForMappingEmToPixels(info, -fh); ranges[i].h_oversample = (byte)spc.h_oversample; ranges[i].v_oversample = (byte)spc.v_oversample; for (j = 0; j < ranges[i].num_chars; ++j) { var x0 = 0; var y0 = 0; var x1 = 0; var y1 = 0; var codepoint = ranges[i].array_of_unicode_codepoints == null ? ranges[i].first_unicode_codepoint_in_range + j : ranges[i].array_of_unicode_codepoints[j]; var glyph = stbtt_FindGlyphIndex(info, codepoint); if (glyph == 0 && (spc.skip_missing != 0 || missing_glyph_added != 0)) { rects[k].w = rects[k].h = 0; } else { stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, scale * spc.h_oversample, scale * spc.v_oversample, 0, 0, &x0, &y0, &x1, &y1); rects[k].w = (int)(x1 - x0 + spc.padding + spc.h_oversample - 1); rects[k].h = (int)(y1 - y0 + spc.padding + spc.v_oversample - 1); if (glyph == 0) { missing_glyph_added = 1; } } ++k; } } return(k); }
/// <summary> /// Creates and initializes a font from ttf/otf/ttc data /// </summary> /// <param name="data"></param> /// <param name="offset"></param> /// <returns>null if the data was invalid</returns> public static stbtt_fontinfo CreateFont(byte[] data, int offset) { var dataCopy = (byte *)CRuntime.malloc(data.Length); Marshal.Copy(data, 0, new IntPtr(dataCopy), data.Length); var info = new stbtt_fontinfo { isDataCopy = true }; if (stbtt_InitFont_internal(info, dataCopy, offset) == 0) { info.Dispose(); return(null); } return(info); }
public static int stbtt_PackFontRangesGatherRects(stbtt_pack_context spc, stbtt_fontinfo info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects) { int i = 0; int j = 0; int k = 0; int missing_glyph_added = (int)(0); k = (int)(0); for (i = (int)(0); (i) < (num_ranges); ++i) { float fh = (float)(ranges[i].font_size); float scale = (float)((fh) > (0) ? stbtt_ScaleForPixelHeight(info, (float)(fh)) : stbtt_ScaleForMappingEmToPixels(info, (float)(-fh))); ranges[i].h_oversample = ((byte)(spc.h_oversample)); ranges[i].v_oversample = ((byte)(spc.v_oversample)); for (j = (int)(0); (j) < (ranges[i].num_chars); ++j) { int x0 = 0; int y0 = 0; int x1 = 0; int y1 = 0; int codepoint = (int)((ranges[i].array_of_unicode_codepoints) == (null) ? ranges[i].first_unicode_codepoint_in_range + j : ranges[i].array_of_unicode_codepoints[j]); int glyph = (int)(stbtt_FindGlyphIndex(info, (int)(codepoint))); if (((glyph) == (0)) && (((spc.skip_missing) != 0) || ((missing_glyph_added) != 0))) { rects[k].w = (int)(rects[k].h = (int)(0)); } else { stbtt_GetGlyphBitmapBoxSubpixel(info, (int)(glyph), (float)(scale * spc.h_oversample), (float)(scale * spc.v_oversample), (float)(0), (float)(0), &x0, &y0, &x1, &y1); rects[k].w = ((int)(x1 - x0 + spc.padding + spc.h_oversample - 1)); rects[k].h = ((int)(y1 - y0 + spc.padding + spc.v_oversample - 1)); if ((glyph) == (0)) { missing_glyph_added = (int)(1); } } ++k; } } return((int)(k)); }
public static int stbtt_PackFontRanges(stbtt_pack_context spc, byte *fontdata, int font_index, stbtt_pack_range *ranges, int num_ranges) { var info = new stbtt_fontinfo(); var i = 0; var j = 0; var n = 0; var return_value = 1; stbrp_rect *rects; for (i = 0; i < num_ranges; ++i) { for (j = 0; j < ranges[i].num_chars; ++j) { ranges[i].chardata_for_range[j].x0 = ranges[i].chardata_for_range[j].y0 = ranges[i].chardata_for_range[j].x1 = ranges[i].chardata_for_range[j].y1 = 0; } } n = 0; for (i = 0; i < num_ranges; ++i) { n += ranges[i].num_chars; } rects = (stbrp_rect *)CRuntime.malloc((ulong)(sizeof(stbrp_rect) * n)); if (rects == null) { return(0); } info.userdata = spc.user_allocator_context; stbtt_InitFont(info, fontdata, stbtt_GetFontOffsetForIndex(fontdata, font_index)); n = stbtt_PackFontRangesGatherRects(spc, info, ranges, num_ranges, rects); stbtt_PackFontRangesPackRects(spc, rects, n); return_value = stbtt_PackFontRangesRenderIntoRects(spc, info, ranges, num_ranges, rects); CRuntime.free(rects); return(return_value); }
public StbTrueTypeSharpSource(byte[] data, StbTrueTypeSharpSettings settings) { if (data == null) { throw new ArgumentNullException(nameof(data)); } _font = CreateFont(data, 0); if (_font == null) { throw new Exception("stbtt_InitFont failed"); } _settings = settings; int ascent, descent, lineGap; stbtt_GetFontVMetrics(_font, &ascent, &descent, &lineGap); _ascent = ascent; _descent = descent; _lineHeight = ascent - descent + lineGap; }
static int stbtt_InitFont(ref stbtt_fontinfo info, FakePtr <byte> data2, int fontstart) { FakePtr <byte> data = (FakePtr <byte>)data2; uint i; info.data = data; info.fontstart = fontstart; info.name = stbtt__find_table(data, fontstart, "name"); // required if (info.name == 0) { return(0); } var format = ttUSHORT(data + info.name); var nameRecordCount = ttUSHORT(data + info.name + 2); var stringOffset = ttUSHORT(data + info.name + 4); var offset = info.name + stringOffset; var nameRecords = new stbtt_name_record[nameRecordCount]; for (i = 0; i < nameRecordCount; ++i) { uint name_record = info.name + 6 + 12 * i; var nr = nameRecords[i]; nr.platformId = ttUSHORT(data + name_record); nr.platformSpecificId = ttUSHORT(data + name_record + 2); nr.languageId = ttUSHORT(data + name_record + 4); nr.nameId = ttUSHORT(data + name_record + 6); nr.length = ttUSHORT(data + name_record + 8); nr.offset = ttUSHORT(data + name_record + 10) + offset; nameRecords[i] = nr; } info.nameRecords = nameRecords; return(1); }
private int LoadFont(stbtt_fontinfo font, byte *data, int dataSize) { return(stbtt_InitFont(font, data, 0)); }
public static void fons__tt_getFontVMetrics(this stbtt_fontinfo font, int *ascent, int *descent, int *lineGap) { stbtt_GetFontVMetrics(font, ascent, descent, lineGap); }
public static int fons__tt_getGlyphKernAdvance(this stbtt_fontinfo font, int glyph1, int glyph2) { return((int)(stbtt_GetGlyphKernAdvance(font, (int)(glyph1), (int)(glyph2)))); }
public static void fons__tt_renderGlyphBitmap(this stbtt_fontinfo font, byte *output, int outWidth, int outHeight, int outStride, float scaleX, float scaleY, int glyph) { stbtt_MakeGlyphBitmap(font, output, (int)(outWidth), (int)(outHeight), (int)(outStride), (float)(scaleX), (float)(scaleY), (int)(glyph)); }
public static int fons__tt_buildGlyphBitmap(this stbtt_fontinfo font, int glyph, float size, float scale, int *advance, int *lsb, int *x0, int *y0, int *x1, int *y1) { stbtt_GetGlyphHMetrics(font, (int)(glyph), advance, lsb); stbtt_GetGlyphBitmapBox(font, (int)(glyph), (float)(scale), (float)(scale), x0, y0, x1, y1); return((int)(1)); }
public static int fons__tt_getGlyphIndex(this stbtt_fontinfo font, int codepoint) { return((int)(stbtt_FindGlyphIndex(font, (int)(codepoint)))); }
public static float fons__tt_getPixelHeightScale(this stbtt_fontinfo font, float size) { return((float)(stbtt_ScaleForPixelHeight(font, (float)(size)))); }
public static int stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context spc, stbtt_fontinfo info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects) { var i = 0; var j = 0; var k = 0; var missing_glyph = -1; var return_value = 1; var old_h_over = (int)spc.h_oversample; var old_v_over = (int)spc.v_oversample; k = 0; for (i = 0; i < num_ranges; ++i) { var fh = ranges[i].font_size; var scale = fh > 0 ? stbtt_ScaleForPixelHeight(info, fh) : stbtt_ScaleForMappingEmToPixels(info, -fh); float recip_h = 0; float recip_v = 0; float sub_x = 0; float sub_y = 0; spc.h_oversample = ranges[i].h_oversample; spc.v_oversample = ranges[i].v_oversample; recip_h = 1.0f / spc.h_oversample; recip_v = 1.0f / spc.v_oversample; sub_x = stbtt__oversample_shift((int)spc.h_oversample); sub_y = stbtt__oversample_shift((int)spc.v_oversample); for (j = 0; j < ranges[i].num_chars; ++j) { var r = &rects[k]; if (r->was_packed != 0 && r->w != 0 && r->h != 0) { var bc = &ranges[i].chardata_for_range[j]; var advance = 0; var lsb = 0; var x0 = 0; var y0 = 0; var x1 = 0; var y1 = 0; var codepoint = ranges[i].array_of_unicode_codepoints == null ? ranges[i].first_unicode_codepoint_in_range + j : ranges[i].array_of_unicode_codepoints[j]; var glyph = stbtt_FindGlyphIndex(info, codepoint); var pad = spc.padding; r->x += pad; r->y += pad; r->w -= pad; r->h -= pad; stbtt_GetGlyphHMetrics(info, glyph, &advance, &lsb); stbtt_GetGlyphBitmapBox(info, glyph, scale * spc.h_oversample, scale * spc.v_oversample, &x0, &y0, &x1, &y1); stbtt_MakeGlyphBitmapSubpixel(info, spc.pixels + r->x + r->y * spc.stride_in_bytes, (int)(r->w - spc.h_oversample + 1), (int)(r->h - spc.v_oversample + 1), spc.stride_in_bytes, scale * spc.h_oversample, scale * spc.v_oversample, 0, 0, glyph); if (spc.h_oversample > 1) { stbtt__h_prefilter(spc.pixels + r->x + r->y * spc.stride_in_bytes, r->w, r->h, spc.stride_in_bytes, spc.h_oversample); } if (spc.v_oversample > 1) { stbtt__v_prefilter(spc.pixels + r->x + r->y * spc.stride_in_bytes, r->w, r->h, spc.stride_in_bytes, spc.v_oversample); } bc->x0 = (ushort)(short)r->x; bc->y0 = (ushort)(short)r->y; bc->x1 = (ushort)(short)(r->x + r->w); bc->y1 = (ushort)(short)(r->y + r->h); bc->xadvance = scale * advance; bc->xoff = x0 * recip_h + sub_x; bc->yoff = y0 * recip_v + sub_y; bc->xoff2 = (x0 + r->w) * recip_h + sub_x; bc->yoff2 = (y0 + r->h) * recip_v + sub_y; if (glyph == 0) { missing_glyph = j; } } else if (spc.skip_missing != 0) { return_value = 0; } else if (r->was_packed != 0 && r->w == 0 && r->h == 0 && missing_glyph >= 0) { ranges[i].chardata_for_range[j] = ranges[i].chardata_for_range[missing_glyph]; } else { return_value = 0; } ++k; } } spc.h_oversample = (uint)old_h_over; spc.v_oversample = (uint)old_v_over; return(return_value); }
public void Dispose() { font = null; GC.Collect(); }
public static int stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context spc, stbtt_fontinfo info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects) { int i = 0; int j = 0; int k = 0; int missing_glyph = (int)(-1); int return_value = (int)(1); int old_h_over = (int)(spc.h_oversample); int old_v_over = (int)(spc.v_oversample); k = (int)(0); for (i = (int)(0); (i) < (num_ranges); ++i) { float fh = (float)(ranges[i].font_size); float scale = (float)((fh) > (0) ? stbtt_ScaleForPixelHeight(info, (float)(fh)) : stbtt_ScaleForMappingEmToPixels(info, (float)(-fh))); float recip_h = 0; float recip_v = 0; float sub_x = 0; float sub_y = 0; spc.h_oversample = (uint)(ranges[i].h_oversample); spc.v_oversample = (uint)(ranges[i].v_oversample); recip_h = (float)(1.0f / spc.h_oversample); recip_v = (float)(1.0f / spc.v_oversample); sub_x = (float)(stbtt__oversample_shift((int)(spc.h_oversample))); sub_y = (float)(stbtt__oversample_shift((int)(spc.v_oversample))); for (j = (int)(0); (j) < (ranges[i].num_chars); ++j) { stbrp_rect *r = &rects[k]; if ((((r->was_packed) != 0) && (r->w != 0)) && (r->h != 0)) { stbtt_packedchar *bc = &ranges[i].chardata_for_range[j]; int advance = 0; int lsb = 0; int x0 = 0; int y0 = 0; int x1 = 0; int y1 = 0; int codepoint = (int)((ranges[i].array_of_unicode_codepoints) == (null) ? ranges[i].first_unicode_codepoint_in_range + j : ranges[i].array_of_unicode_codepoints[j]); int glyph = (int)(stbtt_FindGlyphIndex(info, (int)(codepoint))); int pad = (int)(spc.padding); r->x += (int)(pad); r->y += (int)(pad); r->w -= (int)(pad); r->h -= (int)(pad); stbtt_GetGlyphHMetrics(info, (int)(glyph), &advance, &lsb); stbtt_GetGlyphBitmapBox(info, (int)(glyph), (float)(scale * spc.h_oversample), (float)(scale * spc.v_oversample), &x0, &y0, &x1, &y1); stbtt_MakeGlyphBitmapSubpixel(info, spc.pixels + r->x + r->y * spc.stride_in_bytes, (int)(r->w - spc.h_oversample + 1), (int)(r->h - spc.v_oversample + 1), (int)(spc.stride_in_bytes), (float)(scale * spc.h_oversample), (float)(scale * spc.v_oversample), (float)(0), (float)(0), (int)(glyph)); if ((spc.h_oversample) > (1)) { stbtt__h_prefilter(spc.pixels + r->x + r->y * spc.stride_in_bytes, (int)(r->w), (int)(r->h), (int)(spc.stride_in_bytes), (uint)(spc.h_oversample)); } if ((spc.v_oversample) > (1)) { stbtt__v_prefilter(spc.pixels + r->x + r->y * spc.stride_in_bytes, (int)(r->w), (int)(r->h), (int)(spc.stride_in_bytes), (uint)(spc.v_oversample)); } bc->x0 = (ushort)((short)(r->x)); bc->y0 = (ushort)((short)(r->y)); bc->x1 = (ushort)((short)(r->x + r->w)); bc->y1 = (ushort)((short)(r->y + r->h)); bc->xadvance = (float)(scale * advance); bc->xoff = (float)((float)(x0) * recip_h + sub_x); bc->yoff = (float)((float)(y0) * recip_v + sub_y); bc->xoff2 = (float)((x0 + r->w) * recip_h + sub_x); bc->yoff2 = (float)((y0 + r->h) * recip_v + sub_y); if ((glyph) == (0)) { missing_glyph = (int)(j); } } else if ((spc.skip_missing) != 0) { return_value = (int)(0); } else if (((((r->was_packed) != 0) && ((r->w) == (0))) && ((r->h) == (0))) && ((missing_glyph) >= (0))) { ranges[i].chardata_for_range[j] = (stbtt_packedchar)(ranges[i].chardata_for_range[missing_glyph]); } else { return_value = (int)(0); } ++k; } } spc.h_oversample = (uint)(old_h_over); spc.v_oversample = (uint)(old_v_over); return((int)(return_value)); }