private bool CalculateTextureAndRenderAreas(Rectf renderSettingDestArea, ref Rectf?clippingArea, out Rectf finalRect, ref Rectf texRect) { var dest = (renderSettingDestArea); // apply rendering offset to the destination Rect dest.Offset(d_scaledOffset); // get the rect area that we will actually draw to (i.e. perform clipping) finalRect = clippingArea.HasValue ? dest.GetIntersection(clippingArea.Value) : dest; // check if rect was totally clipped if ((finalRect.Width == 0) || (finalRect.Height == 0)) { return(true); } // Obtain correct scale values from the texture var texelScale = _texture.GetTexelScaling(); var texPerPix = new Lunatics.Mathematics.Vector2(d_imageArea.Width / dest.Width, d_imageArea.Height / dest.Height); // calculate final, clipped, texture co-ordinates texRect = new Rectf((d_imageArea.d_min + ((finalRect.d_min - dest.d_min) * texPerPix)) * texelScale, (d_imageArea.d_max + ((finalRect.d_max - dest.d_max) * texPerPix)) * texelScale); // TODO: This is clearly not optimal but the only way to go with the current // Font rendering system. Distance field rendering would allow us to ignore the // pixel alignment. finalRect.d_min.X = CoordConverter.AlignToPixels(finalRect.d_min.X); finalRect.d_min.Y = CoordConverter.AlignToPixels(finalRect.d_min.Y); finalRect.d_max.X = CoordConverter.AlignToPixels(finalRect.d_max.X); finalRect.d_max.Y = CoordConverter.AlignToPixels(finalRect.d_max.Y); return(false); }
// implemets abstract from base protected override void AddImageRenderGeometryToWindowImpl(Window srcWindow, Rectf destRect, ColourRect modColours, Rectf?clipper, bool clipToDisplay) { // get final image to use. var img = IsImageFetchedFromProperty() ? srcWindow.GetProperty <Image>(ImagePropertyName) : Image; // do not draw anything if image is not set. if (img == null) { return; } var horzFormatting = HorizontalFormatting.Get(srcWindow); var vertFormatting = VerticalFormatting.Get(srcWindow); int horzTiles, vertTiles; float xpos, ypos; var imgSz = img.GetRenderedSize(); // calculate final colours to be used ColourRect finalColours; InitColoursRect(srcWindow, modColours, out finalColours); // calculate initial x co-ordinate and horizontal tile count according to formatting options switch (horzFormatting) { case Base.HorizontalFormatting.Stretched: imgSz.Width = destRect.Width; xpos = destRect.Left; horzTiles = 1; break; case Base.HorizontalFormatting.Tiled: xpos = destRect.Left; horzTiles = Math.Abs((int)((destRect.Width + (imgSz.Width - 1)) / imgSz.Width)); break; case Base.HorizontalFormatting.LeftAligned: xpos = destRect.Left; horzTiles = 1; break; case Base.HorizontalFormatting.CentreAligned: xpos = destRect.Left + CoordConverter.AlignToPixels((destRect.Width - imgSz.Width) * 0.5f); horzTiles = 1; break; case Base.HorizontalFormatting.RightAligned: xpos = destRect.Right - imgSz.Width; horzTiles = 1; break; default: throw new InvalidRequestException("An unknown HorizontalFormatting value was specified."); } // calculate initial y co-ordinate and vertical tile count according to formatting options switch (vertFormatting) { case Base.VerticalFormatting.Stretched: imgSz.Height = destRect.Height; ypos = destRect.Top; vertTiles = 1; break; case Base.VerticalFormatting.Tiled: ypos = destRect.Top; vertTiles = Math.Abs((int)((destRect.Height + (imgSz.Height - 1)) / imgSz.Height)); break; case Base.VerticalFormatting.TopAligned: ypos = destRect.Top; vertTiles = 1; break; case Base.VerticalFormatting.CentreAligned: ypos = destRect.Top + CoordConverter.AlignToPixels((destRect.Height - imgSz.Height) * 0.5f); vertTiles = 1; break; case Base.VerticalFormatting.BottomAligned: ypos = destRect.Bottom - imgSz.Height; vertTiles = 1; break; default: throw new InvalidRequestException("An unknown VerticalFormatting value was specified."); } // perform final rendering (actually is now a caching of the images which will be drawn) var imgRenderSettings = new ImageRenderSettings(Rectf.Zero, null, !clipToDisplay, finalColours); imgRenderSettings.DestArea.Top = ypos; imgRenderSettings.DestArea.Bottom = ypos + imgSz.Height; for (uint row = 0; row < vertTiles; ++row) { imgRenderSettings.DestArea.Left = xpos; imgRenderSettings.DestArea.Right = xpos + imgSz.Width; for (uint col = 0; col < horzTiles; ++col) { // use custom clipping for right and bottom edges when tiling the imagery if (((vertFormatting == Base.VerticalFormatting.Tiled) && row == vertTiles - 1) || ((horzFormatting == Base.HorizontalFormatting.Tiled) && col == horzTiles - 1)) { imgRenderSettings.ClipArea = clipper.HasValue ? clipper.Value.GetIntersection(destRect) : destRect; } // not tiliing, or not on far edges, just used passed in clipper (if any). else { imgRenderSettings.ClipArea = clipper; } // add geometry for image to the target window. var geomBuffers = img.CreateRenderGeometry(imgRenderSettings); srcWindow.AppendGeometryBuffers(geomBuffers); imgRenderSettings.DestArea.d_min.X += imgSz.Width; imgRenderSettings.DestArea.d_max.X += imgSz.Width; } imgRenderSettings.DestArea.d_min.Y += imgSz.Height; imgRenderSettings.DestArea.d_max.Y += imgSz.Height; } }
protected List <GeometryBuffer> CreateRenderGeometryForImage(Image image, VerticalFormatting vertFmt, HorizontalFormatting horzFmt, Rectf destRect, ColourRect colours, Rectf?clipper, bool clipToDisplay) { int horzTiles, vertTiles; float xpos, ypos; var imgSz = image.GetRenderedSize(); // calculate initial x co-ordinate and horizontal tile count according to formatting options switch (horzFmt) { case HorizontalFormatting.Stretched: imgSz.Width = destRect.Width; xpos = destRect.Left; horzTiles = 1; break; case HorizontalFormatting.Tiled: xpos = destRect.Left; horzTiles = Math.Abs((int)((destRect.Width + (imgSz.Width - 1)) / imgSz.Width)); break; case HorizontalFormatting.LeftAligned: xpos = destRect.Left; horzTiles = 1; break; case HorizontalFormatting.CentreAligned: xpos = destRect.Left + CoordConverter.AlignToPixels((destRect.Width - imgSz.Width) * 0.5f); horzTiles = 1; break; case HorizontalFormatting.RightAligned: xpos = destRect.Right - imgSz.Width; horzTiles = 1; break; default: throw new InvalidRequestException("An unknown HorizontalFormatting value was specified."); } // calculate initial y co-ordinate and vertical tile count according to formatting options switch (vertFmt) { case VerticalFormatting.Stretched: imgSz.Height = destRect.Height; ypos = destRect.Top; vertTiles = 1; break; case VerticalFormatting.Tiled: ypos = destRect.Top; vertTiles = Math.Abs((int)((destRect.Height + (imgSz.Height - 1)) / imgSz.Height)); break; case VerticalFormatting.TopAligned: ypos = destRect.Top; vertTiles = 1; break; case VerticalFormatting.CentreAligned: ypos = destRect.Top + CoordConverter.AlignToPixels((destRect.Height - imgSz.Height) * 0.5f); vertTiles = 1; break; case VerticalFormatting.BottomAligned: ypos = destRect.Bottom - imgSz.Height; vertTiles = 1; break; default: throw new InvalidRequestException("An unknown VerticalFormatting value was specified."); } // Create the render geometry var geomBuffers = new List <GeometryBuffer>(); var renderSettings = new ImageRenderSettings(Rectf.Zero, null, !clipToDisplay, colours); renderSettings.DestArea.d_min.Y = ypos; renderSettings.DestArea.d_max.Y = ypos + imgSz.Height; for (uint row = 0; row < vertTiles; ++row) { renderSettings.DestArea.d_min.X = xpos; renderSettings.DestArea.d_max.X = xpos + imgSz.Width; for (uint col = 0; col < horzTiles; ++col) { // use custom clipping for right and bottom edges when tiling the imagery if (((vertFmt == VerticalFormatting.Tiled) && row == vertTiles - 1) || ((horzFmt == HorizontalFormatting.Tiled) && col == horzTiles - 1)) { renderSettings.ClipArea = clipper.HasValue ? clipper.Value.GetIntersection(destRect) : destRect; } else { // not tiling, or not on far edges, just used passed in clipper (if any). renderSettings.ClipArea = clipper; } geomBuffers.AddRange(image.CreateRenderGeometry(renderSettings)); renderSettings.DestArea.d_min.X += imgSz.Width; renderSettings.DestArea.d_max.X += imgSz.Width; } renderSettings.DestArea.d_min.Y += imgSz.Height; renderSettings.DestArea.d_max.Y += imgSz.Height; } return(geomBuffers); }