public void DownScaleThis (int newWidth, int newHeight, QBitmapData dest, PixelFormat format) { var srcWidth = mBitmapData.Width; var srcHeight = mBitmapData.Height; if (format != PixelFormat.Format32bppArgb) throw new Exception ("DownsScale32 only works on 32 bit images"); float xscale = (float)srcWidth / newWidth; float yscale = (float)srcHeight / newHeight; byte r = 0, g = 0, b = 0, a = 0; float summedR = 0f; float summedG = 0f; float summedB = 0f; float summedA = 0f; int left, right, top, bottom; //the area of old pixels covered by the new bitmap float targetStartX, targetEndX; float targetStartY, targetEndY; float leftF, rightF, topF, bottomF; //edges of new pixel in old pixel coords float weight; float weightScale = xscale * yscale; float totalColourWeight = 0f; for (int m = 0; m < newHeight; m++) { for (int n = 0; n < newWidth; n++) { leftF = n * xscale; rightF = (n + 1) * xscale; topF = m * yscale; bottomF = (m + 1) * yscale; left = (int)leftF; right = (int)rightF; top = (int)topF; bottom = (int)bottomF; if (left < 0) left = 0; if (top < 0) top = 0; if (right >= srcWidth) right = srcWidth - 1; if (bottom >= srcHeight) bottom = srcHeight - 1; summedR = 0f; summedG = 0f; summedB = 0f; summedA = 0f; totalColourWeight = 0f; for (int j = top; j <= bottom; j++) { for (int i = left; i <= right; i++) { targetStartX = Math.Max (leftF, i); targetEndX = Math.Min (rightF, i + 1); targetStartY = Math.Max (topF, j); targetEndY = Math.Min (bottomF, j + 1); weight = (targetEndX - targetStartX) * (targetEndY - targetStartY); this.GetPixel32 (i, j, ref r, ref g, ref b, ref a); summedA += weight * a; if (a != 0) { summedR += weight * r; summedG += weight * g; summedB += weight * b; totalColourWeight += weight; } } } summedR /= totalColourWeight; summedG /= totalColourWeight; summedB /= totalColourWeight; summedA /= weightScale; if (summedR < 0) summedR = 0f; if (summedG < 0) summedG = 0f; if (summedB < 0) summedB = 0f; if (summedA < 0) summedA = 0f; if (summedR >= 256) summedR = 255; if (summedG >= 256) summedG = 255; if (summedB >= 256) summedB = 255; if (summedA >= 256) summedA = 255; dest.PutPixel32 (n, m, (byte)summedR, (byte)summedG, (byte)summedB, (byte)summedA); } } }
public void BlurAlpha (int radius, int passes, QBitmapData tmp, int width, int height) { byte a = 0; int summedA; int weight = 0; int xpos, ypos, x, y, kx, ky; for (int pass = 0; pass < passes; pass++) { //horizontal pass for (y = 0; y < height; y++) { for (x = 0; x < width; x++) { summedA = weight = 0; for (kx = -radius; kx <= radius; kx++) { xpos = x + kx; if (xpos >= 0 && xpos < width) { this.GetAlpha32 (xpos, y, ref a); summedA += a; weight++; } } summedA /= weight; tmp.PutAlpha32 (x, y, (byte)summedA); } } //vertical pass for (x = 0; x < width; ++x) { for (y = 0; y < height; ++y) { summedA = weight = 0; for (ky = -radius; ky <= radius; ky++) { ypos = y + ky; if (ypos >= 0 && ypos < height) { tmp.GetAlpha32 (x, ypos, ref a); summedA += a; weight++; } } summedA /= weight; this.PutAlpha32 (x, y, (byte)summedA); } } } }
public NxFont Load(string filePath, float height, float downSampleFactor, NxFontLoaderConfiguration loaderConfig) { if (loaderConfig == null) { throw new ArgumentNullException ("loaderConfig"); } float fontScale; TransformViewport? transToVp = NxFont.SetupTransformViewport (height, loaderConfig.TransformToCurrentOrthogProjection, loaderConfig.Transform, out fontScale); var qfont = new NxFont(); var internalConfig = new QFontLoaderConfiguration(); var fontData = new QFontData (); qfont.SetData (fontData); QFontDataInformation fontInfo = null; using (var fs = File.OpenRead (filePath)) { fontInfo = fontData.LoadFromStream (fs); } var bitmapFiles = fontInfo.GenerateBitmapPageNames (filePath); var bitmapPages = new List<NxBitmap> (); foreach (var bitmapFileName in bitmapFiles) { // TODO : STREAM BASED REPLACEMENT // https://support.microsoft.com/en-us/kb/814675 // GDI+ require the bitmap files to be locked as indexed image // during the lifetime i.e. maybe reloaded from disk using (var fs = File.OpenRead (bitmapFileName)) { var parent = new Bitmap (fs); var data = parent.LockBits ( new Rectangle(0,0, parent.Width, parent.Height) ,System.Drawing.Imaging.ImageLockMode.ReadWrite ,parent.PixelFormat); var target = new QBitmapData (data); var qb = new NxBitmap (parent, target); bitmapPages.Add (qb); } } var glyphList = fontData.InitialiseQFontData (fontInfo, ref bitmapPages, downSampleFactor, internalConfig); if (loaderConfig.ShadowConfig != null) { qfont.DropShadow = Helper.BuildDropShadow<NxFont, NxBitmap> ( bitmapPages, glyphList.ToArray (), loaderConfig.ShadowConfig, Helper.ToArray (fontInfo.CharSet), internalConfig.KerningConfig.alphaEmptyPixelTolerance); } fontData.InitialiseKerningPairs (fontInfo, bitmapPages, glyphList, internalConfig); if (loaderConfig.ShadowConfig != null) qfont.Options.DropShadowActive = true; if (transToVp != null) qfont.Options.TransformToViewport = transToVp; qfont.InitialiseGlyphRenderer(loaderConfig.CharacterOutput, loaderConfig.FontGlyphRenderer, loaderConfig.DropShadowRenderer); return qfont; }