private void PutChar0(byte encodedChar, int X1, int Y1, G3Font font, G3Color fontColor, G3Color haloColor) { int charwidth = font.Chars[encodedChar].width; if (charwidth == 0) return; X1 -= charwidth >> 1; Y1 -= font.FontHeight >> 1; if (X1 < 0 || Y1 < 0 || (X1 + charwidth) >= SurfaceWidth || (Y1 + font.FontHeight) >= SurfaceHeight) return; ushort pencolor = fontColor.RGB565; ushort outlinecolor = haloColor.RGB565; ushort* dst = &Surface.DIBImage[Y1 * SurfaceWidth + X1]; int dstStride = SurfaceWidth - charwidth; fixed (byte* b = font.Chars[encodedChar].data) { byte* d = b; for (int y = 0; y < font.FontHeight; y++, dst += dstStride) { for (int x = 0; x < charwidth; x++, d++, dst++) { if (*d == G3Font.FONT) { *dst = pencolor; // *dst = 0; } else if (*d == G3Font.HALO) { *dst = outlinecolor; // *dst = 65535; } } } } }
private void DrawTextAlignRight(IList<byte[]> lines, Rectangle r, G3Font font, G3Color fontColor, G3Color haloColor) { int x = r.X + r.Width - 1; int y = r.Y + (r.Height / 2); y = y - ((font.FontHeight * lines.Count) / 2); y = y + (font.FontHeight / 2); foreach (var l in lines) { int w = font.TextWidth(l) / 2; if (r.Contains(x, y - (font.FontHeight / 2)) && r.Contains(x, y + (font.FontHeight / 2))) _DrawTextC(l, font, x - w - 1, y, fontColor, haloColor); y = y + font.FontHeight; } }
private void PutChar(byte char1254, int angle, int PosX, int PosY, G3Font font, G3Color fontColor, G3Color haloColor) { if (angle == 0) { PutChar0(char1254, PosX, PosY, font, fontColor, haloColor); return; } // Font'un iç rengi SİYAH byte fontR = fontColor.R; byte fontG = fontColor.G; byte fontB = fontColor.B; // Font'un dış halo rengi BEYAZ byte haloR = haloColor.R; byte haloG = haloColor.G; byte haloB = haloColor.B; // get source image size int sourcewidth = font.Chars[char1254].width; int sourceheight = font.FontHeight; int angleCos = SinCos11.cos[angle]; int angleSin = SinCos11.sin[angle]; int halfWidth = sourcewidth / 2; int halfHeight = sourceheight / 2; int halfNewWidth, halfNewHeight; int newWidth, newHeight; // rotate corners int cx1 = (halfWidth * angleCos); int cy1 = (halfWidth * angleSin); int cx2 = (halfWidth * angleCos - halfHeight * angleSin); int cy2 = (halfWidth * angleSin + halfHeight * angleCos); int cx3 = (-halfHeight * angleSin); int cy3 = (halfHeight * angleCos); halfNewWidth = Math.Max(Math.Max(cx1, cx2), Math.Max(cx3, 0)) - Math.Min(Math.Min(cx1, cx2), Math.Min(cx3, 0)); halfNewHeight = Math.Max(Math.Max(cy1, cy2), Math.Max(cy3, 0)) - Math.Min(Math.Min(cy1, cy2), Math.Min(cy3, 0)); //halfNewWidth >>= 11; //halfNewHeight >>= 11; //halfNewHeight++; //halfNewWidth++; //newHeight = halfNewHeight * 2; //newWidth = halfNewWidth * 2; if ((halfNewWidth & 0x7ff) > 1024) { halfNewWidth >>= 11; newWidth = (halfNewWidth * 2) + 1; } else { halfNewWidth >>= 11; newWidth = (halfNewWidth * 2); } if ((halfNewHeight & 0x7ff) > 1024) { halfNewHeight >>= 11; newHeight = (halfNewHeight * 2) + 1; } else { halfNewHeight >>= 11; newHeight = (halfNewHeight * 2); } PosX -= halfNewWidth; PosY -= halfNewHeight; // Clipping if (PosX < 0 || PosY < 0) return; if (PosX + newWidth >= SurfaceWidth || PosY + newHeight >= SurfaceHeight) return; // Alt satıra geçiş için int dstOffset = SurfaceWidth - newWidth; // do the job byte[] src = font.Chars[char1254].data; ushort* dst = &Surface.DIBImage[(SurfaceWidth * PosY) + PosX]; // ------------------------------------ // rotate using bilinear interpolation // ------------------------------------ int cx, cy; int ox, oy; int dx1, dy1, dx2, dy2; int ox1, oy1, ox2, oy2; int ymax = sourceheight - 1; int xmax = sourcewidth - 1; // Bu satırlar eğer fontlar için renk desteği istersek bu şekilde olacak. //byte fontR = (byte)((pencolor & 0xF800) >> 8); //byte fontG = (byte)((pencolor & 0x7E0) >> 3); //byte fontB = (byte)((pencolor & 0x1F) << 3); //byte haloR = (byte)((outlinecolor & 0xF800) >> 8); //byte haloG = (byte)((outlinecolor & 0x7E0) >> 3); //byte haloB = (byte)((outlinecolor & 0x1F) << 3); // RGB cy = -halfNewHeight; for (int y = 0; y < newHeight; y++) { cx = -halfNewWidth; for (int x = 0; x < newWidth; x++) { ox = ((angleCos * cx + angleSin * cy) + (halfWidth << 11)); oy = ((-angleSin * cx + angleCos * cy) + (halfHeight << 11)); // top-left coordinate ox1 = (ox >> 11); oy1 = (oy >> 11); if ((ox1 < 0) || (oy1 < 0) || (ox1 >= sourcewidth) || (oy1 >= sourceheight)) { //dst[2] = fillR; //dst[1] = fillG; //dst[0] = fillB; } else { // bottom-right coordinate ox2 = (ox1 == xmax) ? ox1 : ox1 + 1; oy2 = (oy1 == ymax) ? oy1 : oy1 + 1; if ((dx1 = ox - (ox1 << 11)) < 0) dx1 = 0; dx2 = 2048 - dx1; if ((dy1 = oy - (oy1 << 11)) < 0) dy1 = 0; dy2 = 2048 - dy1; ///////////////////////////// byte p1R, p1G, p1B; switch (src[oy1 * sourcewidth + ox1]) { case G3Font.TRANSPARENT: p1R = (byte)((*dst & 0xF800) >> 8); p1G = (byte)((*dst & 0x7E0) >> 3); p1B = (byte)((*dst & 0x1F) << 3); break; case G3Font.HALO: p1R = haloR; p1G = haloG; p1B = haloB; break; default: p1R = fontR; p1G = fontG; p1B = fontB; break; } ///////////////////////////// byte p2R, p2G, p2B; switch (src[oy1 * sourcewidth + ox2]) { case G3Font.TRANSPARENT: p2R = (byte)((*dst & 0xF800) >> 8); p2G = (byte)((*dst & 0x7E0) >> 3); p2B = (byte)((*dst & 0x1F) << 3); break; case G3Font.HALO: p2R = haloR; p2G = haloG; p2B = haloB; break; default: p2R = fontR; p2G = fontG; p2B = fontB; break; } ///////////////////////////// byte p3R, p3G, p3B; switch (src[oy2 * sourcewidth + ox1]) { case G3Font.TRANSPARENT: p3R = (byte)((*dst & 0xF800) >> 8); p3G = (byte)((*dst & 0x7E0) >> 3); p3B = (byte)((*dst & 0x1F) << 3); break; case G3Font.HALO: p3R = haloR; p3G = haloG; p3B = haloB; break; default: p3R = fontR; p3G = fontG; p3B = fontB; break; } ///////////////////////////// byte p4R, p4G, p4B; switch (src[oy2 * sourcewidth + ox2]) { case G3Font.TRANSPARENT: p4R = (byte)((*dst & 0xF800) >> 8); p4G = (byte)((*dst & 0x7E0) >> 3); p4B = (byte)((*dst & 0x1F) << 3); break; case G3Font.HALO: p4R = haloR; p4G = haloG; p4B = haloB; break; default: p4R = fontR; p4G = fontG; p4B = fontB; break; } // interpolate using 4 points // red int red = ((dy2 * ((dx2 * p1R + dx1 * p2R) >> 11) + dy1 * ((dx2 * p3R + dx1 * p4R) >> 11)) >> 11); // green int green = ((dy2 * ((dx2 * p1G + dx1 * p2G) >> 11) + dy1 * ((dx2 * p3G + dx1 * p4G) >> 11)) >> 11); // blue int blue = ((dy2 * ((dx2 * p1B + dx1 * p2B) >> 11) + dy1 * ((dx2 * p3B + dx1 * p4B) >> 11)) >> 11); //////////////////////////////////////////// *dst = (ushort)(((red >> 3) << 11) | ((green >> 2) << 5) | (blue >> 3)); //////////////////////////////////////////// } cx++; dst++; } cy++; dst += dstOffset; } }
private void DrawTextAlignBottomCenter(IList<byte[]> lines, Rectangle r, G3Font font, G3Color fontColor, G3Color haloColor) { int x = r.X + (r.Width / 2); // Orta nokta (X) int y = r.Y + r.Height; //(Y) // y = y - ((font.FontHeight * lines.Count) / 2); // y = y - (font.FontHeight / 2); y = y - (font.FontHeight * lines.Count); foreach (var l in lines) { if (r.Contains(x, y - (font.FontHeight / 2)) && r.Contains(x, y + (font.FontHeight / 2))) _DrawTextC(l, font, x, y, fontColor, haloColor); y = y + font.FontHeight; } }
private IList<byte[]> ClipText(byte[] encodedByteCharArray, Rectangle r, G3Font font) { IList<byte[]> list = new List<byte[]>(); int x = r.Left, y = r.Top; int Start = 0, End = -1, lastSpace = -1; int i = 0, totalWidth = 0; while (i < encodedByteCharArray.Length) { // en son rastlanılan SPACE veya ENTER!!! if (encodedByteCharArray[i] == 32 || encodedByteCharArray[i] == 10) { lastSpace = i; } totalWidth += font.Chars[encodedByteCharArray[i]].width; if ((totalWidth > r.Width) || (encodedByteCharArray[i] == 10)) { if (lastSpace != -1) { End = lastSpace - 1; list.Add(encodedByteCharArray.Clone(Start, End - Start + 1)); // Reset lastSpace = -1; totalWidth = 0; Start = End + 2; i = End + 1; } else { End = i - 1; list.Add(encodedByteCharArray.Clone(Start, End - Start + 1)); // Reset lastSpace = -1; totalWidth = 0; Start = End + 1; i = End; } } i++; } if (Start < encodedByteCharArray.Length) { list.Add(encodedByteCharArray.Clone(Start, encodedByteCharArray.Length - Start)); } return list; }
public void _DrawTextC(byte[] encodedByteCharArray, G3Font font, int X1, int Y1, G3Color fontColor, G3Color haloColor) { if (encodedByteCharArray == null || font == null) return; // half width float offset = X1 - (font.TextWidth(encodedByteCharArray) / 2f); for (int k = 0; k < encodedByteCharArray.Length; k++) { byte byteChar = encodedByteCharArray[k]; if (k == 0) { offset += (font.Chars[byteChar].width / 2f); } else { offset += (font.Chars[encodedByteCharArray[k - 1]].width / 2f); offset += ((font.Chars[byteChar].width + font.SpaceBetweenChars) / 2f); } if (byteChar != 32) PutChar0(byteChar, (int)offset, Y1, font, fontColor, haloColor); } }
public void DrawText(string text, Encoding encoding, G3Font font, G3Color fontColor, G3Color haloColor, TextAlign align, Rectangle r) { if (text == null || string.IsNullOrEmpty(text) || font == null) return; byte[] chars = encoding.GetBytes(text); IList<byte[]> lines = ClipText(chars, r, font); switch (align) { case TextAlign.Center: DrawTextAlignCenter(lines, r, font, fontColor, haloColor); break; case TextAlign.Left: DrawTextAlignLeft(lines, r, font, fontColor, haloColor); break; case TextAlign.Right: DrawTextAlignRight(lines, r, font, fontColor, haloColor); break; case TextAlign.UpperLeft: throw new NotImplementedException(); case TextAlign.BottomLeft: throw new NotImplementedException(); case TextAlign.TopCenter: throw new NotImplementedException(); case TextAlign.BottomCenter: DrawTextAlignBottomCenter(lines, r, font, fontColor, haloColor); break; case TextAlign.UpperRight: throw new NotImplementedException(); case TextAlign.BottomRight: throw new NotImplementedException(); } }
public CompoundFont(G3Font font, G3Color fontColor, G3Color haloColor) { this.Font = font; this.FontColor = fontColor; this.HaloColor = haloColor; }