GDI compatiable with direct2d not working when using pushlayer and poplayer - gdi

I am working on a project, and try to convert GDI rendering into direct2d rendering.
Sometimes I need to use ID2D1GdiInteropRenderTarget interface to rendering some GDI content to direct2d's render target.
Here is the problem:
If I use GetDC() ReleaseDC() between PushLayer and PopLayer. The content rendered to the HDC is gone, not composited into rendertarget. But If I use GerDC() ReleaseDC between PushAxisAlignedClip and PopAxisAlignedClip, it works correctly.
Why It doesn't work between PushLayer and PopLayer, I need to use pushlayer to clip a round rect regeion.
Code is like as follows:
ID2D1HwndRenderTarget* render_target = NULL;
ID2D1GdiInteropRenderTarget* gdi_render_target = NULL;
//create ID2D1HwndRenderTarget and query ID2D1GdiInteropRenderTarget...
render_target->BeginDraw();
D2D1_LAYER_PARAMETERS params = D2D1::LayerParameters(round_rect, round_rect_geometry);
render_target->PushLayer(params, render_layer_);
HDC hdc = NULL;
gdi_render_target->GetDC(D2D1_DC_INITIALIZE_MODE_COPY, &hdc);
// Draw Line with hdc. some code is Omit.
::MoveToEx(hdc, rc.left, rc.top, &ptTemp);
::LineTo(hdc, rc.right, rc.bottom);
gdi_render_target->ReleaseDC(0);
render_target->PopLayer();
render_target->EndDraw();

Related

How to add fontawasome icon as a layer in geotools using javafx (Desktop App)?

I have been using java 17 and I'm unable to add icons into the map as a layer. please help me.
void drawTarget(double x, double y) {
SimpleFeatureTypeBuilder builder = new SimpleFeatureTypeBuilder();
builder.setName("MyFeatureType");
builder.setCRS( DefaultGeographicCRS.WGS84 ); // set crs
builder.add("location", LineString.class); // add geometry
// build the type
SimpleFeatureType TYPE = builder.buildFeatureType();
// create features using the type defined
SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(TYPE);
// GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory();
// Coordinate[] coords =
// new Coordinate[] {new Coordinate(79,25.00), new Coordinate(x, y)};
// line = geometryFactory.createLineString(coords);
// ln = new javafx.scene.shape.Line();
FontAwesomeIcon faico = new FontAwesomeIcon();
faico.setIconName("FIGHTER_JET");
faico.setX(76);
faico.setY(25);
faico.setVisible(true);
// TranslateTransition trans = new TranslateTransition();
// trans.setNode(faico);
featureBuilder.add(faico);
SimpleFeature feature = featureBuilder.buildFeature("FeaturePoint");
DefaultFeatureCollection featureCollection = new DefaultFeatureCollection("external", TYPE);
featureCollection.add(feature); // Add feature 1, 2, 3, etc
Style style5 = SLD.createLineStyle(Color.YELLOW, 2f);
Layer layer5 = new FeatureLayer(featureCollection, style5);
map.addLayer(layer5);
// mapFrame.getMapPane().repaint();
}
I want to add a font-awesome icon to the map
Currently, your code is attempting to use an Icon as a Geometry in your feature. I'm guessing that's what isn't working since you don't say.
If you want to use an Icon to display the location of a Feature then you will need two things.
A valid geometry in your feature, probably a point (since an Icon is normally a point)
A valid Style to be used by the Renderer to draw your feature(s) on the map. Currently, you are asking for the line in your feature to be drawn using a yellow line (style5 = SLD.createLineStyle(Color.YELLOW, 2f);)
I can't really help with step 1, since I don't know where your fighter jet currently is.
For step 2 I suggest you look at the SLD resources to give you some clues of how the styling system works before going on the manual to see how GeoTools implements that.
Since you are trying to add an Icon I suggest you'd need something like:
List<GraphicalSymbol> symbols = new ArrayList<>();
symbols.add(sf.externalGraphic(svg, "svg", null)); // svg preferred
symbols.add(sf.externalGraphic(png, "png", null)); // png preferred
symbols.add(sf.mark(ff.literal("circle"), fill, stroke)); // simple circle backup plan
Expression opacity = null; // use default
Expression size = ff.literal(10);
Expression rotation = null; // use default
AnchorPoint anchor = null; // use default
Displacement displacement = null; // use default
// define a point symbolizer of a small circle
Graphic city = sf.graphic(symbols, opacity, size, rotation, anchor, displacement);
PointSymbolizer pointSymbolizer =
sf.pointSymbolizer("point", ff.property("the_geom"), null, null, city);
rule1.symbolizers().add(pointSymbolizer);
featureTypeStyle.rules().add(rule1);
But that assumes that you can convert your FontAwesomeIcon into a static representation that the renderer can draw (png, svg). If it doesn't work like that (I don't use JavaFX) then you may need to add a new MarkFactory to handle them.

NSAttributedString drawRect doesn't draw images on-screen on Mojave

I have a working app that draws NSAttributedStrings into a custom view. The NSAttributedStrings can included embedded images. This works on versions of macOS prior to Mojave. The app can display the strings on screen, print them, and save them to image files.
This is apparently broken under Mojave. Weirdly, printing and saving to image files still works; but on-screen, the strings display only the text and not the embedded images. Proper space is left for the images, but that space is blank.
I've tested by building a small app that shows a window with an NSTextField (a label) and a custom view. It makes a single NSAttributedString with an embedded image. It applies that string to the attributedStringValue of the label, and also calls drawInRect: on the same string in the drawRect: method of the custom view. In the label, the string is displayed correctly, image and all. But in the custom view, only the text appears, and the space where the image should be is blank.
Anybody got a clue why this is happening on Mojave but not on earlier versions of macOS?
Here is the code that makes the string (and caches it, for re-use):
static NSMutableAttributedString* sgAttrString = nil;
/*
* Creates an attributed string the first time it's called,
* then returns that same string each time it's called.
*/
+ (NSAttributedString*)getAttributedString
{
if (sgAttrString == nil)
{
NSFont* font = [NSFont fontWithName:#"Helvetica" size:24.0];
NSDictionary *attrs = #{
NSFontAttributeName: font
};
sgAttrString = [[NSMutableAttributedString alloc] initWithString:#"Daisy: " attributes:attrs];
NSImage* daisy = [NSImage imageNamed:#"daisy.png"];
[daisy setSize:NSMakeSize(24,24)];
NSTextAttachment *attachment = [[NSTextAttachment alloc] init];
// I'm aware that attachment.image is available only on macOS 10.11 and later.
// It's not an issue in my real project.
attachment.image = daisy;
NSMutableAttributedString* imageStr = [[NSMutableAttributedString alloc] init];
[imageStr setAttributedString:[NSAttributedString attributedStringWithAttachment:attachment]];
[sgAttrString appendAttributedString:imageStr];
[sgAttrString appendAttributedString: [[NSAttributedString alloc] initWithString:#" !!" attributes:attrs]];
}
return sgAttrString;
}
Here is the code that applies the string to the NSTextField:
NSAttributedString* str = [Utilities getAttributedString];
self.label.attributedStringValue = str;
And here is the code that draws the string in a custom NSView:
NSAttributedString* str = [Utilities getAttributedString];
[str drawInRect:NSMakeRect(50,50, 300, 40)];
Again, this behavior seems to occur only in Mojave! Thanks in advance for any help.

Unable to Create Image of Special Characters

I have written a imageHandler.ashx in c# which draw image of a text on a fly . Its takes a parameter string txt. The Handler is called from Asp.net page. At the time of calling, if text contains the character # or any special character .it Does not create the images of #,or any special character's given to it.
According to my R&D the problem is with a Graphics.DrawString() method some how its is unable to write special characters.so please tell me how to create a image of a special characters
Code I am using :
String signatureText = HttpUtility.HtmlDecode(signatureText);
System.Drawing.Text.PrivateFontCollection fontCollection = new System.Drawing.Text.PrivateFontCollection();
FontFamily ff1 = fontCollection.Families[0];
// Initialize graphics
RectangleF rectF = new RectangleF(0, 0, imgWidth, imgHeight);
Bitmap pic = new Bitmap((int) rectF.Width,imgHeight, PixelFormat.Format24bppRgb);
Graphics g = Graphics.FromImage(pic);
//g.SmoothingMode = SmoothingMode.Default;
// g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
Font font1 = new Font(ff1, imgHeight, FontStyle.Regular, GraphicsUnit.Pixel);
float bestFontSize = BestFontSize(g, new Size(imgWidth, imgHeight), font1, signatureText);
Font font2 = new Font(ff1, bestFontSize, FontStyle.Regular, GraphicsUnit.Pixel);
// Set colors
Color fontColor = Color.Black;
Color rectColor = Color.White;
SolidBrush fgBrush = new SolidBrush(fontColor);
SolidBrush bgBrush = new SolidBrush(rectColor);
// Rectangle or ellipse?
g.FillRectangle(bgBrush, rectF);
// Set font direction & alignment
StringFormat format = new StringFormat();
//format.FormatFlags = StringFormatFlags.DirectionRightToLeft;
format.Alignment = StringAlignment.Center;
format.LineAlignment = StringAlignment.Center;
// Finally, draw the font
g.DrawString(signatureText, font2, fgBrush, rectF, format);
pic = (Bitmap) ImageUtility.ResizeImageWithAspectRatio(pic, imgWidth, imgHeight, true);
pic.Save(context.Response.OutputStream, System.Drawing.Imaging.ImageFormat.Jpeg);
Any help is Appreciated Thanks in Advance
DrawString() don't have any problem while writing special characters if they are provided in font file (.ttf)
Problem can be in the following line
System.Drawing.Text.PrivateFontCollection fontCollection = new System.Drawing.Text.PrivateFontCollection();
Specially with the font you get in ff1
FontFamily ff1 = fontCollection.Families[0];
In your case it means Font ff1 don't have representation for some or all special characters.
Since I don't know how many font files you are getting from fontCollection.Families, if fontCollection.Families contain more than one font file try next one.
FontFamily ff1 = fontCollection.Families[1]; // and so on.
Or try to add font file with all special characters (if System.Drawing.Text.PrivateFontCollection is absolutely necessary ).
Alternatively you can use InstalledFontCollection instead of PrivateFontCollection
System.Drawing.Text.InstalledFontCollection fontCollection = new System.Drawing.Text.InstalledFontCollection();
Which will give you all installed fonts of the system on which application is running through its Families property InstalledFontCollection.
Easiest way is (if only one font is required, as you are using only one font in your provided code)
using constructor of FontFamily class with a string type parameter FontFamily.
Consider replacing this line
FontFamily ff1 = fontCollection.Families[0];
With this one
FontFamily fontFamily1 = new FontFamily("Arial");
Arial must be installed on the system where application is running.
Hope this will help.
DrawString doesn't have any problem with drawing special characters like # or copyright (I just tested it and produced the image below).
The problem might be from your URL parameter. Try encoding your text using Server.UrlEncode when passing the text, and then Server.UrlDecode before giving it to DrawString.

Why does Image.GetThumbnailImage work differently on IIS6 and IIS7.5?

Bit of a strange question and I don't know whether anyone will have come across this one before.
We have a ASP.net page generating physical thumbnail jpeg files on a filesystem and copying fullsize images to a different location. So we input one image and we get a complete copy in one location and a small image 102*68 in a different location.
We're currently looking to finally move away from IIS6 on Server 2003 to IIS7.5 on Server 2008R2, except there's on problem.
On the old system (so IIS6/Server 2003) the black borders are removed and the image stays at the correct ration. On the new system (IIS7.5/Server 2008) the thumbnails are rendered exactly as they exist in the JPEG, with black borders, but this makes the thumbnail slightly squashed and obviously includes ugly black borders.
Anyone know why this might be happening? I've done a google and can't seem to find out which behaviour is "correct". My gut tells me that the new system is correctly rendering the thumbnail as it exists, but I don't know.
Anyone have any suggestions how to solve the problem?
I think as suggested it is the .net differences. not IIS.
Just re write your code, your save a lot of time, very simple thing to do.
Here is a image handler i wrote a while ago that re draws any image to your settings.
public class image_handler : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
// set file
string ImageToDraw = context.Request.QueryString["FilePath"];
ImageToDraw = context.Server.MapPath(ImageToDraw);
// Grab images to work on's true width and height
Image ImageFromFile = Image.FromFile(ImageToDraw);
double ImageFromFileWidth = ImageFromFile.Width;
double ImageFromFileHeight = ImageFromFile.Height;
ImageFromFile.Dispose();
// Get required width and work out new dimensions
double NewHeightRequired = 230;
if (context.Request.QueryString["imageHeight"] != null)
NewHeightRequired = Convert.ToDouble(context.Request.QueryString["imageHeight"]);
double DivTotal = (ImageFromFileHeight / NewHeightRequired);
double NewWidthValue = (ImageFromFileWidth / DivTotal);
double NewHeightVale = (ImageFromFileHeight / DivTotal);
NewWidthValue = ImageFromFileWidth / (ImageFromFileWidth / NewWidthValue);
NewHeightVale = ImageFromFileHeight / (ImageFromFileHeight / NewHeightVale);
// Set new width, height
int x = Convert.ToInt16(NewWidthValue);
int y = Convert.ToInt16(NewHeightVale);
Bitmap image = new Bitmap(x, y);
Graphics g = Graphics.FromImage(image);
Image thumbnail = Image.FromFile(ImageToDraw);
// Quality Control
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.SmoothingMode = SmoothingMode.HighQuality;
g.PixelOffsetMode = PixelOffsetMode.HighQuality;
g.CompositingQuality = CompositingQuality.HighQuality;
g.DrawImage(thumbnail, 0, 0, x, y);
g.Dispose();
image.Save(context.Response.OutputStream, ImageFormat.Jpeg);
image.Dispose();
}
public bool IsReusable
{
get
{
return true;
}
}

Mystery coordinate offset on getCharBoundaries

I've ran into a weird problem with getCharBoundaries, I could not figure out what coordinate space the coordinates returned from the function was in. What ever I tried I could not get it to match up with what I expected.
So I made a new project and and added simple code to highlight the last charater in a textfield, and all of a sudden it worked fine. I then tried to copy over the TextField that had been causing me problems, into the new project. And now the same weird offset appeared 50px on the x axis. Everything else was spot on.
So after some headscracthing comparing the two TextFields, I simply can not see a difference in their properties or transformation.
So I was hoping that someone might now what property might affect the coordinates returned by getCharBoundaries.
I am using Flash CS4.
I've just had exactly the same problem and thought I'd help out by offering what my findings are. With a help from this thread, I tried to find everything that wasn't 'default' about the textfield I was using. I found that when I had switched my TextFormatAlign (or 'align' in the IDE) and TextFieldAutoSize properties to 'LEFT' as opposed to 'CENTER', it solved the problem.
A little late in the game perhaps, but worth knowing for anyone running into the same problem. This was the only thread I could find that raised the right flag...
Well the getCharBoundaries returns the boundaries in the textfield coordinate system. Where the origin is topleft corner of the textfield.
getCharBoundaries does not take into consideration the scrolling. you need to check if there are scrollbars on its parent (textarea) and if so relocate. One quick way of doing it is using localtoglobal and globaltolocal. Use the first to translate from the textfield coordinate system to the application coordinate system and then use the second to translate from the app coordinate system to the coordinate system of the parent of the textfield which is the textarea. I'm fine tuning a my method to get char boundaries i will publish it today on my blog
http://flexbuzz.blogspot.com/
Works For Me(tm) (Flex Builder AS3 project):
[Embed(systemFont="Segoe UI", fontWeight="bold", fontName="emb",
mimeType="application/x-font")]
private var EmbeddedFont:Class;
public function ScratchAs3()
{
stage.scaleMode = 'noScale';
stage.align = 'tl';
var m:Matrix = new Matrix(.8, .1, -.1, 1.1, 26, 78);
var t:TextField = new TextField();
t.autoSize = 'left';
t.wordWrap = false;
t.embedFonts = true;
t.defaultTextFormat = new TextFormat("emb", 100, 0, true);
t.transform.matrix = m;
t.text = "TEST STRING.";
addChild(t);
var r:Rectangle = t.getCharBoundaries(8);
var tl:Point = m.transformPoint(r.topLeft);
var tr:Point = m.transformPoint(new Point(r.right, r.top));
var bl:Point = m.transformPoint(new Point(r.left, r.bottom));
var br:Point = m.transformPoint(r.bottomRight);
graphics.beginFill(0xFF, .6);
graphics.moveTo(tl.x, tl.y);
graphics.lineTo(tr.x, tr.y);
graphics.lineTo(br.x, br.y);
graphics.lineTo(bl.x, bl.y);
graphics.lineTo(tl.x, tl.y);
}
To literally answer your question, it returns the coordinates in the TextField's coordinate system, not it's parent, and it is affected by DisplayObject.transform.matrix, which is the backing for the .x, .y, .scaleX, .scaleY, .width, .height, and .rotation properties.
What ever it was the solution was simple to add a new TextField, never found out what property screwed everything up.
The first answer is correct in most cases. However if your field is parented to another movie clip it may still return the wrong y coordinate. try this code:
//if this doesn't work:
myTextFormat = new TextFormat();
myTextFormat.align = TextFormatAlign.LEFT;
myFieldsParent.myField.autoSize = TextFieldAutoSize.LEFT;
myFieldsParent.myField.setTextFormat( myTextFormat);
//try this:
var x = myFieldsParent.myField.getCharBoundaries(o).x;
var y = myFieldsParent.myField.getCharBoundaries(o).y;
var myPoint:Point = new Point(myField.getCharBoundaries(o).x,myField.getCharBoundaries(o).y);
var pt:Point = new Point(myFieldsParent.myField.getCharBoundaries(o).x, myFieldsParent.myField.getCharBoundaries(o).y);
pt = myFieldsParent.myField.localToGlobal(pt);
//pt is the variable containing the coordinates of the char in the stage's coordinate space. You may still need to offset it with a fixed value but it should be constant.
I didn't test this code as I have adapted this example from code that is embedded into my project so I apologize if I'm missing something...

Resources