private static Int32Rect ToTinyBitmap1bpp(WriteableBitmap glyphBitmap, AntialiasingLevel antialiasLevel, out BitArray[] bitmapDataRows, out BitArray antialiasData) { Contract.Requires(glyphBitmap != null, "Glyph bitmap cannot be null."); Contract.Requires(glyphBitmap.Format.BitsPerPixel == 32, "Glyph bitmap must be in 32 bits per pixel format."); int height = glyphBitmap.PixelHeight; int width = glyphBitmap.PixelWidth; Int32Thickness inkBox = new Int32Thickness(width, height, -1, -1); bitmapDataRows = new BitArray[height]; antialiasData = null; int antialiasStep = 0; if (antialiasLevel != AntialiasingLevel.None) { antialiasStep = OpacityOpaque / ((int)antialiasLevel * (int)antialiasLevel); antialiasData = new BitArray(0); } for (int y = 0; y < bitmapDataRows.Length; y++) { BitArray bitmapDataRow = bitmapDataRows[y] = new BitArray(width); for (int x = 0; x < width; x++) { byte pixel = Marshal.ReadByte(glyphBitmap.BackBuffer, y * glyphBitmap.BackBufferStride + x * glyphBitmap.Format.BitsPerPixel / BitsPerByte + 0); if (pixel > 0) { bitmapDataRow[x] = true; if (y < inkBox.Top) { inkBox.Top = y; } if (x < inkBox.Left) { inkBox.Left = x; } if (y > inkBox.Bottom) { inkBox.Bottom = y; } if (x > inkBox.Right) { inkBox.Right = x; } if (antialiasLevel != AntialiasingLevel.None) { antialiasData.ApendMsb(pixel / antialiasStep, (int)antialiasLevel); } } } } int boxWidth = Math.Max(0, inkBox.Right - inkBox.Left + 1); int boxHeight = Math.Max(0, inkBox.Bottom - inkBox.Top + 1); return(new Int32Rect(inkBox.Left, inkBox.Top, boxWidth, boxHeight)); }
private void InitializeMetrics() { Contract.Requires(_typeface != null, "Typeface cannot be null."); Contract.Requires(_mapping != null, "Mapping cannot be null."); Contract.Requires(_transform != null, "Transform must be initialized first."); ushort glyph = _mapping.Glyph.GetValueOrDefault(); checked { _emHeight = (ushort)Round(_typeface.Height * _emSize); _emBaseline = (short)Round(_typeface.Baseline * _emSize); } // System.Diagnostics.Debug.WriteLine("{2}: {0} {1}", // _typeface.LeftSideBearings[glyph] * _emSize, // _typeface.RightSideBearings[glyph] * _emSize, (char)(int)_mapping.Character); if (_antialiasLevel == AntialiasingLevel.None) { _emSideBearing = new Int32Thickness( Round(_typeface.LeftSideBearings[glyph] * _emSize), Round(_typeface.TopSideBearings[glyph] * _emSize), Round(_typeface.RightSideBearings[glyph] * _emSize), Round(_typeface.BottomSideBearings[glyph] * _emSize) ); } else { _emSideBearing = new Int32Thickness( Floor(_typeface.LeftSideBearings[glyph] * _emSize), Floor(_typeface.TopSideBearings[glyph] * _emSize), Floor(_typeface.RightSideBearings[glyph] * _emSize), Floor(_typeface.BottomSideBearings[glyph] * _emSize) ); } Rect advance = new Rect(new Size(_typeface.AdvanceWidths[glyph], _typeface.AdvanceHeights[glyph])); Rect advanceTransformed = _transform.TransformBounds(advance); _emAdvance = new Int32Vector( Round(advanceTransformed.Width * _emSize), Round(advanceTransformed.Height * _emSize) ); if (!_transform.Value.IsIdentity) { Rect boundBox = _run.ComputeInkBoundingBox(); Rect advanceBox = boundBox.Add(_emSideBearing); Rect boundBoxTransformed = _transform.TransformBounds(boundBox); Rect advanceBoxTransformed = _transform.TransformBounds(advanceBox); Thickness bearingTransformed = boundBox.Subtract(advanceBox); _emSideBearing = new Int32Thickness( Round(bearingTransformed.Left), Round(bearingTransformed.Top), Round(bearingTransformed.Right), Round(bearingTransformed.Bottom) ); } }