public static int DrawString(this WriteableBitmap bmp, int x0, int y0, IntRect cliprect, Color fontColor, PortableFontDesc typeface, string text) { var font = GetFont(typeface); return(bmp.DrawString(x0, y0, cliprect, fontColor, font, text)); }
public static unsafe void DrawLetterVertical(this BitmapContext context, int x0, int y0, IntRect cliprect, Color fontColor, GrayScaleLetterGlyph glyph, Boolean topToBottom) { if (glyph.Items == null) { return; } // Use refs for faster access (really important!) speeds up a lot! int w = context.Width; int h = context.Height; var pixels = context.Pixels; int fr = fontColor.R; int fg = fontColor.G; int fb = fontColor.B; int xmin = cliprect.Left; int ymin = cliprect.Top; int xmax = cliprect.Right; int ymax = cliprect.Bottom; if (xmin < 0) { xmin = 0; } if (ymin < 0) { ymin = 0; } if (xmax >= w) { xmax = w - 1; } if (ymax >= h) { ymax = h - 1; fixed(GrayScaleLetterGlyph.Item *items = glyph.Items) { int itemCount = glyph.Items.Length; GrayScaleLetterGlyph.Item *currentItem = items; for (int i = 0; i < itemCount; i++, currentItem++) { int x; int y; if (topToBottom) { x = x0 - currentItem->Y; y = y0 + currentItem->X; } else { x = x0 + currentItem->Y; y = y0 - currentItem->X; } int alpha = currentItem->Alpha; if (x < xmin || y < ymin || x > xmax || y > ymax) { continue; } int color = pixels[y * w + x]; int r = ((color >> 16) & 0xFF); int g = ((color >> 8) & 0xFF); int b = ((color) & 0xFF); r = (((r << 12) + (fr - r) * alpha) >> 12) & 0xFF; g = (((g << 12) + (fg - g) * alpha) >> 12) & 0xFF; b = (((b << 12) + (fb - b) * alpha) >> 12) & 0xFF; pixels[y * w + x] = (0xFF << 24) | (r << 16) | (g << 8) | (b); } } }
public static unsafe void DrawLetter(this BitmapContext context, int x0, int y0, IntRect cliprect, ClearTypeLetterGlyph glyph) { //if (glyph.Instructions == null) return; if (glyph.Items == null) { return; } // Use refs for faster access (really important!) speeds up a lot! int w = context.Width; int h = context.Height; var pixels = context.Pixels; int xmin = cliprect.Left; int ymin = cliprect.Top; int xmax = cliprect.Right; int ymax = cliprect.Bottom; if (xmin < 0) { xmin = 0; } if (ymin < 0) { ymin = 0; } if (xmax >= w) { xmax = w - 1; } if (ymax >= h) { ymax = h - 1; fixed(ClearTypeLetterGlyph.Item *items = glyph.Items) { int itemCount = glyph.Items.Length; ClearTypeLetterGlyph.Item *currentItem = items; for (int i = 0; i < itemCount; i++, currentItem++) { int x = x0 + currentItem->X; int y = y0 + currentItem->Y; int color = currentItem->Color; if (x < xmin || y < ymin || x > xmax || y > ymax) { continue; } pixels[y * w + x] = color; } } }
public static int DrawString(this WriteableBitmap bmp, int x0, int y0, IntRect cliprect, Color fontColor, GlyphFont font, string text) { return(DrawString(bmp, x0, y0, cliprect, fontColor, null, font, text)); }
public static unsafe void DrawLetter(this BitmapContext context, int x0, int y0, IntRect cliprect, ClearTypeLetterGlyph glyph) { // if (glyph.Instructions == null) return; if (glyph.Items == null) { return; } // Use refs for faster access (really important!) speeds up a lot! int w = context.Width; int h = context.Height; var pixels = context.Pixels; int xmin = cliprect.Left; int ymin = cliprect.Top; int xmax = cliprect.Right; int ymax = cliprect.Bottom; if (xmin < 0) { xmin = 0; } if (ymin < 0) { ymin = 0; } if (xmax >= w) { xmax = w - 1; } if (ymax >= h) { ymax = h - 1; } fixed(ClearTypeLetterGlyph.Item *items = glyph.Items) { int itemCount = glyph.Items.Length; ClearTypeLetterGlyph.Item *currentItem = items; // if (x0 >= xmin && y0 >= ymin && x0 + glyph.Width < xmax && y0 + glyph.Height < ymax) // { // for (int i = 0; i < itemCount; i++, currentItem++) // { // pixels[(y0 + currentItem->Y) * w + x0 + currentItem->X] = currentItem->Color; // } // } // else // { for (int i = 0; i < itemCount; i++, currentItem++) { int x = x0 + currentItem->X; int y = y0 + currentItem->Y; int color = currentItem->Color; if (x < xmin || y < ymin || x > xmax || y > ymax) { continue; } pixels[(y * w) + x] = color; } // } } // fixed (int *instructions = glyph.Instructions) // { // int* current = instructions; // while (*current != -1) // { // int dy = *current++; // int dx = *current++; // int count0 = *current++; // int y = y0 + dy; // if (y >= ymin && y <= ymax) // { // int x = x0 + dx; // int* dst = pixels + y*w + x; // int* src = current; // int count = count0; // if (x < xmin) // { // int dmin = xmin - x; // x += dmin; // dst += dmin; // src += dmin; // count -= dmin; // } // if (x + count - 1 > xmax) // { // int dmax = x + count - 1 - xmax; // count -= dmax; // } // if (count > 0) // { // NativeMethods.memcpy(dst, src, count * 4); // //if (count < 10) // //{ // // while (count > 0) // // { // // *dst++ = *src++; // // count--; // // } // //} // //else // //{ // // NativeMethods.memcpy(dst, src, count*4); // //} // } // } // current += count0; // } // } }
public static int DrawString(this WriteableBitmap bmp, int x0, int y0, IntRect cliprect, Color fontColor, Color?bgColor, GlyphFont font, string text) { if (text == null) { return(0); } int dx = 0, dy = 0; int textwi = 0; using (var context = bmp.GetBitmapContext()) { foreach (char ch in text) { if (ch == '\n') { if (dx > textwi) { textwi = dx; } dx = 0; dy += font.TextHeight; } if (x0 + dx <= cliprect.Right) { if (font.IsClearType) { if (!bgColor.HasValue) { throw new Exception("Clear type fonts must have background specified"); } var letter = font.GetClearTypeLetter(ch, fontColor, bgColor.Value); if (letter == null) { continue; } context.DrawLetter(x0 + dx, y0 + dy, cliprect, letter); dx += letter.Width; } else { var letter = font.GetGrayScaleLetter(ch); if (letter == null) { continue; } context.DrawLetter(x0 + dx, y0 + dy, cliprect, fontColor, letter); dx += letter.Width; } } } } if (dx > textwi) { textwi = dx; } return(textwi); }
/// <summary> /// scrolls content of given rectangle /// </summary> /// <param name="bmp"></param> /// <param name="dy">if greater than 0, scrolls down, else scrolls up</param> /// <param name="rect"></param> public static unsafe void ScrollY(this WriteableBitmap bmp, int dy, IntRect rect, Color?background = null) { int bgcolor = WriteableBitmapExtensions.ConvertColor(background ?? Colors.White); using (var context = bmp.GetBitmapContext()) { // Use refs for faster access (really important!) speeds up a lot! int w = context.Width; int h = context.Height; var pixels = context.Pixels; int xmin = rect.Left; int ymin = rect.Top; int xmax = rect.Right; int ymax = rect.Bottom; if (xmin < 0) { xmin = 0; } if (ymin < 0) { ymin = 0; } if (xmax >= w) { xmax = w - 1; } if (ymax >= h) { ymax = h - 1; } int xcnt = xmax - xmin + 1; int ycnt = ymax - ymin + 1; if (xcnt <= 0) { return; } if (dy > 0) { for (int y = ymax; y >= ymin + dy; y--) { int ydstidex = y; int ysrcindex = y - dy; if (ysrcindex < ymin || ysrcindex > ymax) { continue; } NativeMethods.memcpy(pixels + (ydstidex * w) + xmin, pixels + (ysrcindex * w) + xmin, xcnt * 4); } } if (dy < 0) { for (int y = ymin; y <= ymax - dy; y++) { int ysrcindex = y - dy; int ydstidex = y; if (ysrcindex < ymin || ysrcindex > ymax) { continue; } NativeMethods.memcpy(pixels + (ydstidex * w) + xmin, pixels + (ysrcindex * w) + xmin, xcnt * 4); } } if (dy < 0) { bmp.FillRectangle(xmin, ymax + dy + 1, xmax, ymax, bgcolor); } if (dy > 0) { bmp.FillRectangle(xmin, ymin, xmax, ymin + dy - 1, bgcolor); } } }
/// <summary> /// scrolls content of given rectangle /// </summary> /// <param name="bmp"></param> /// <param name="dx">if greater than 0, scrolls right, else scrolls left</param> /// <param name="rect"></param> public static unsafe void ScrollX(this WriteableBitmap bmp, int dx, IntRect rect, Color?background = null) { int bgcolor = WriteableBitmapExtensions.ConvertColor(background ?? Colors.White); using (var context = bmp.GetBitmapContext()) { // Use refs for faster access (really important!) speeds up a lot! int w = context.Width; int h = context.Height; var pixels = context.Pixels; int xmin = rect.Left; int ymin = rect.Top; int xmax = rect.Right; int ymax = rect.Bottom; if (xmin < 0) { xmin = 0; } if (ymin < 0) { ymin = 0; } if (xmax >= w) { xmax = w - 1; } if (ymax >= h) { ymax = h - 1; } int xcnt = xmax - xmin + 1; int ycnt = ymax - ymin + 1; int srcx = xmin, dstx = xmin; if (dx < 0) { xcnt += dx; dstx = xmin; srcx = xmin - dx; } if (dx > 0) { xcnt -= dx; srcx = xmin; dstx = xmin + dx; } if (xcnt <= 0) { return; } int *yptr = pixels + (w * ymin); for (int y = ymin; y <= ymax; y++, yptr += w) { NativeMethods.memcpy(yptr + dstx, yptr + srcx, xcnt * 4); } if (dx < 0) { bmp.FillRectangle(xmax + dx + 1, ymin, xmax, ymax, bgcolor); } if (dx > 0) { bmp.FillRectangle(xmin, ymin, xmin + dx - 1, ymax, bgcolor); } } }
public static void DrawRectangle(this WriteableBitmap bmp, IntRect rect, Color color) { var col = ConvertColor(color); bmp.DrawRectangle(rect.Left, rect.Top, rect.Right, rect.Bottom, col); }