I want to add border around TextBlock programatically in Windows Store Application.
How can I do this?
Thanks.
Create new project and add this code in OnNavigatedTo event.
protected override void OnNavigatedTo(NavigationEventArgs e)
{
var tb = new TextBlock()
{
Text = "...TextBlock with border...",
FontSize = 20
};
//To get actual height and width of TextBlock
tb.Arrange(new Rect(0, 0, Window.Current.Bounds.Width, Window.Current.Bounds.Height));
tb.Measure(new Size(Window.Current.Bounds.Width, Window.Current.Bounds.Height));
var border = new Border()
{
BorderThickness = new Thickness(3),
BorderBrush = new SolidColorBrush(Windows.UI.Colors.Red),
Height = tb.ActualHeight + 10,
Width = tb.ActualWidth + 10
};
var rootGrid = (Grid)(((Page)this).Content);
rootGrid.Children.Add(border);
border.Child = tb;
}
Related
I have a map using Xamarin.Forms.Googlemap in my xamarin forms app.
Is there a way to click on what is behind a pin?
I am creating polygons on the googlemap and then adding custom pins with orchard names on it.
Pin pin = new Pin()
{
Icon = CreateLabels(orchardname, 60),
Flat = true,
Address = string.Empty,
Label = string.Empty,
Position = Xamarin.Forms.GoogleMaps.Bounds.FromPositions(allpositions).Center,
Anchor = new Point(0.5, -1),
IsVisible = _showPropertyzoom
};
protected BitmapDescriptor CreateLabels(string Text, int size)
{
SKBitmap bitmap;
SKCanvas bitmapCanvas;
SKColor white = new SKColor(255,255,255);
SKColor blue = new SKColor(0,88,164);
SKPaint textPaintStroke = new SKPaint { TextSize = size, StrokeWidth=3, Color = white, FakeBoldText=true, Style = SKPaintStyle.Stroke};
SKPaint textPaint = new SKPaint { TextSize = size, Color = blue };
SKRect bounds = new SKRect();
textPaint.MeasureText(Text, ref bounds);
bitmap = new SKBitmap((int)(bounds.Right + 10), (int)(bounds.Height +5));
using (bitmapCanvas = new SKCanvas(bitmap))
{
bitmapCanvas.Clear();
bitmapCanvas.DrawText(Text, bounds.Left, -bounds.Top, textPaintStroke);
bitmapCanvas.DrawText(Text, bounds.Left, -bounds.Top, textPaint);
}
SKData data = SKImage.FromBitmap(bitmap).Encode(SKEncodedImageFormat.Png, 100);
var image = BitmapDescriptorFactory.FromStream(data.AsStream());
return image;
}
The problem i am having is when i click on a polygon to trigger the polygonclicked event i am clicking on the pin so nothing happens.
I can't just use the pinclicked event to trigger the polygonclicked event in this case, because the pin/label can span across multiple polygons.
I need to come up with a way to watermark user generated HTML and display it to the user.
I played around with modifying the HTML by setting a background image, but the solution didn't work if the any html element contained a background color or image.
So I thought it would be easier to display the HTML in a web browser control and watermark the control. Boy was I wrong.
I tried creating a user control and derive from WebBrowser and overwrite the paint method. That didn't work.
Next idea was to just draw on top of a webbrowser control.
here's what I've come up with. In this example I slapped a label, webbrowser control and two picture boxes on a form. I create the image and set it to both picture boxes. I put one picture box over the label and the other over the watermark.
The picturebox over the label displayed as I expected, but the picturebox over the webbrowser control did not.
I'm out of ideas. Any suggestions?
public partial class Form1 : Form
{
string WatermarkText = "Confidential";
Font WatermarkFont = new Font("Microsoft Sans Serif", 24, FontStyle.Bold);
int WatermarkAngle = 45;
Color WatermarkColor = Color.PaleTurquoise;
public Form1()
{
InitializeComponent();
AllowTransparency = true;
label1.AutoSize = false;
label1.Text = "Test Text";
label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
webBrowser1.Navigate("http://www.google.com");
var img = creategraphics(WatermarkText);
label1.Size = pictureBox2.Size = pictureBox1.Size = img.Size;
label1.Controls.Add(pictureBox1);
pictureBox1.Image = img;
pictureBox1.BackColor = Color.Transparent;
pictureBox1.Location = new Point(0, 0);
webBrowser1.Controls.Add(pictureBox2);
pictureBox2.Image = img;
pictureBox2.BackColor = Color.Transparent;
pictureBox2.Location = new Point(0, 0);
}
Image creategraphics(string text)
{
if (String.IsNullOrWhiteSpace(text)) return null;
var size = getWatermarkSize(text, WatermarkAngle, WatermarkFont, out double hypotenuse);
var img = new Bitmap(size.Width, size.Height);
var g = Graphics.FromImage(img);
var brush = new SolidBrush(WatermarkColor);
var stringFormat = new StringFormat() { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center };
g.RotateTransform((float)-WatermarkAngle);
g.DrawString(text, WatermarkFont, brush, new Point(0, (int)hypotenuse / 2), stringFormat);
return img;
}
private static Size getWatermarkSize(string text, int angle, Font font, out double hypotenuse)
{
if (angle > 90) throw new ArgumentOutOfRangeException("angle");
using (var bitmap = new Bitmap(1, 1))
using (var graphics = Graphics.FromImage(bitmap))
{
var size = graphics.MeasureString(text, font);
hypotenuse = size.Width + size.Height;
double radians = (angle / 180.0) * Math.PI;
var width = (Math.Cos(radians) * size.Width) + (Math.Sin(radians) * size.Height);
var height = (Math.Cos(radians) * size.Height) + (Math.Sin(radians) * size.Width);
return new Size((int)width, (int)height);
}
}
}
This is what I get
I'm using geoTools 14.1
I'm trying to plot on an image some points
This is the code I'm using:
double[][] points = new double[8][2];
points[0] = new double[]{45.46433710338643, 9.190417528152478};
points[1] = new double[]{45.46195085146914, 9.189746320685355};
points[2] = new double[]{45.460062304163635, 9.19015527826191};
points[3] = new double[]{45.472950871127445, 9.17363731952788};
points[4] = new double[]{45.4737153001908,9.203728795018847};
points[5] = new double[]{45.4849795331724,9.20162835217198};
points[6] = new double[]{45.48560542313713,9.195953607559215};
points[7] = new double[]{45.48348421787171,9.188765287399292};
final SimpleFeatureType TYPE = DataUtilities.createType("Location",
"location:Point:srid=3857,"+// <- the geometry attribute: Point type
"nome:String," + // <- a String attribute
"id:Integer" // a number attribute
);
FeatureCollection<SimpleFeatureType, SimpleFeature> collection = new DefaultFeatureCollection();
GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory(null);
SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(TYPE);
CoordinateReferenceSystem pointSrc = CRS.decode("EPSG:4326");
CoordinateReferenceSystem targetCRS = CRS.decode("EPSG:3857");
MathTransform transform = CRS.findMathTransform(pointSrc, targetCRS);
for (int i = 0; i < points.length; i++)
{
double[] coords = points[i];
Point point = geometryFactory.createPoint(new Coordinate(coords[0], coords[1]));
Point converted = (Point) JTS.transform( point, transform);
featureBuilder.add(converted);
featureBuilder.add("Punto "+i);
featureBuilder.add(i);
SimpleFeature feature = featureBuilder.buildFeature(""+i);
logger.info(""+feature+" feature.getDefaultGeometry() "+feature.getDefaultGeometry()+ " feature.getDefaultGeometryProperty() "+feature.getDefaultGeometryProperty());
((DefaultFeatureCollection)collection).add(feature);
}
String wellKnownName = "Circle";
Style style = SLD.createPointStyle(wellKnownName,Color.RED,Color.RED,0f,10f);
FeatureLayer fl = new FeatureLayer(collection, style);
fl.setVisible(true);
fl.setSelected(true);
logger.info(""+fl);
mapcontent.addLayer((org.geotools.map.Layer)fl); //"1010177.1917802,5688070.7096562,1029133.5747922,5704122.4855938"
ReferencedEnvelope bounds = new ReferencedEnvelope(1010177.1917802,1029133.5747922,5688070.7096562, 5704122.4855938, targetCRS);
BufferedImage ret = buildImage(mapcontent, 5000, 5000, bounds, Color.white);
ImageIO.write((RenderedImage) ret, "png", new File("/home/angelo/Scrivania/immagineResult.png"));
It seems to me all correct, but the generated image contains no point.
This is the generated image
As you can see it's all white; I was expecting only 8 red circles on the image... Is there any error in my code? Am I doing anything wrong?
Thank you
Angelo
UPDATE: added build image method
public BufferedImage buildImage(final MapContent map, final int imageWidth,final int imageHeight,ReferencedEnvelope bounds,Color bgcolor) {
GTRenderer renderer = new StreamingRenderer();
renderer.setMapContent(map);
renderer.setMapContent(map);
Rectangle imageBounds = null;
ReferencedEnvelope mapBounds = bounds;
try {
if(bounds==null) mapBounds = map.getMaxBounds();
imageBounds = new Rectangle(imageWidth, imageHeight);
} catch (Exception e) {
failed to access map layers
throw new RuntimeException(e);
}
BufferedImage image = new BufferedImage(imageBounds.width, imageBounds.height, BufferedImage.TYPE_4BYTE_ABGR);
Graphics2D gr = image.createGraphics();
int type = AlphaComposite.SRC;
gr.setComposite(AlphaComposite.getInstance(type));
Color c = new Color(bgcolor.getRed(), bgcolor.getGreen(), bgcolor.getBlue(), 0);
gr.setBackground(bgcolor);
gr.setColor(c);
gr.fillRect(0, 0, image.getWidth(), image.getHeight());
type = AlphaComposite.SRC_OVER;
gr.setComposite(AlphaComposite.getInstance(type));
try {
renderer.paint(gr, imageBounds, bounds);
} catch (Exception e) {
throw new RuntimeException(e);
}
return image;
}
After a lot of playing I have found the problem :-) There is no bug in your code! There are in fact 8 red dots in that white image, but they are very hard to find!
As the above image shows at 2000% zoom (and panning along the top edge) you will find a dot (I'm assuming the others are there) - the simple answer is either to make the dots 10 times bigger (100px) or the image much smaller (500x500) and in both cases the dots are immediately visible.
I want to be able to cahce HTML text as bitmap, for use in AlivePDF. My testing works well with TextArea or if the component is on the Stage or visible. But I want to be able to crunch text blocks that dont necessarily sit on screen. Does anyone know how to do this?
What I have failing so far
public static function rasterizeText( text:String, width:int = 100, height:int = 100, x:int = 0, y:int = 0 ):BitmapData {
var textRenderer:TextArea = new TextArea();
textRenderer.width = width;
textRenderer.height = height;
textRenderer.htmlText = text;
var bitdata:BitmapData = new BitmapData(width, height, true, 0xFF000000)
bitdata.draw( textRenderer );
return bitdata;
}
Your code should work fine. There is no need to add textRenderer to the stage in order to draw it into the BitmapData. You are drawing your textRenderer onto a solid black background. Maybe your text is also black and that is why you can not see it?
Try changing 0xFF000000 to e.g. 0xFFFF0000 and see if the text will show up.
No it wasn't a color issue. Also I had the color set to FF000000 which at least should have been showing up black. TextArea didn't seem to play nice with bitmaps, although TextField works perfectly fine.
Edit: I'm guessing TextArea wasn't working as spark or mx because they're a FlexSprite thingy, which act differently to normal AS3 Sprites. They'll defer rendering until they're added to the display list.
Working function:
public function rasterizeText( text:String,
width:int = 100, height:int = 100 ):BitmapData {
var tf:TextField = new TextField();
tf.multiline = true;
tf.wordWrap = true;
tf.width = width;
tf.height = height;
tf.htmlText = text;
var bd:BitmapData = new BitmapData(width, height, true,0x00000000);
bd.draw(tf);
return bd;
}
This was not working (I tried mx & spark textarea components):
public function rasterizeText( text:String,
width:int = 100, height:int = 100 ):BitmapData {
var textRenderer:TextArea = new TextArea();
textRenderer.width = width;
textRenderer.height = height;
textRenderer.textFlow = TextConverter.importToFlow( text, TextConverter.TEXT_FIELD_HTML_FORMAT );
var bitdata:BitmapData = new BitmapData( width, height, false, 0xFF000000 )
bitdata.draw( textRenderer );
return bitdata;
}
However it would work when drawing from the Stage:
public function rasterizeText( text:String,
width:int = 100, height:int = 100 ):BitmapData {
var textRenderer:TextArea = new TextArea();
textRenderer.width = width;
textRenderer.height = height;
textRenderer.textFlow = TextConverter.importToFlow( text, TextConverter.TEXT_FIELD_HTML_FORMAT );
canvas.addElement( textRenderer );
var bitdata:BitmapData = new BitmapData( width, height, false, 0xFF000000 )
bitdata.draw( canvas );
return bitdata;
}
Ok, my mind is boggling over this issue im having. I know this might seem like such an easy issue and I can't understand why I cant figure it out but none the less I can't and I've just about given up. Here's the issue:
I have a sprite container which is supposed to hold a bunch of thumbnails to videos. I am able to populate the container with all the videos and the whole works but obviously if I add a bunch of videos its going to exceed the size of the flash document so I need to add a UIScrollBar (which I did) now the scrollbars target is set to the container but isnt allowing me to scroll and if im correct this is because the container doesnt have a set height. So Im trying to set the height of this container but the second I try setting the height or even width all my thumbnails I used to be able to see are gone! It's as if the size is being set to 0 when its not I've even tried to set it to a specified size just to test and nothing. Anyways heres my code if anyone can help out I'd really appreciate it! Thanks in advance!
import fl.controls.UIScrollBar;
var videoList:XMLList;
var numVideos:Number;
var current_Video:Number = 0;
var video_position:Number;
var video_paused:Boolean;
var xmlPlaylist:String;
//XML File setup
var playlist_xml:XML;
var myLoader:URLLoader = new URLLoader();
//Playlist setup
var thumb_width:Number;
var thumb_height:Number;
var thumbs_x:Number;
var thumbs_y:Number;
var main_container:Sprite;
var thumbs:Sprite;
var scrollbar:UIScrollBar;
//Loader Data
this.loaderInfo.addEventListener(Event.COMPLETE, loaderComplete);
function loaderComplete(e:Event):void
{
var myQueryStrings = this.loaderInfo.parameters;
xmlPlaylist = myQueryStrings.pList;
myLoader.load(new URLRequest(xmlPlaylist + "?uniq=" + new Date().getTime()));
}
myLoader.addEventListener(Event.COMPLETE, processXML);
function processXML(e:Event):void {
playlist_xml = new XML(e.target.data);
numVideos = playlist_xml.video.length();
videoList = playlist_xml.video;
thumb_width = playlist_xml.#thumb_width;
thumb_height = playlist_xml.#thumb_height;
thumbs_x = playlist_xml.#thumbs_x;
thumbs_y = playlist_xml.#thumbs_y;
current_Video = Math.round(Math.random()*(numVideos-1))+1;
current_Video--;
startPlayer();
}
function startPlayer()
{
makeContainers();
callThumbs();
setVideo(current_Video);
}
function makeContainers():void
{
main_container = new Sprite();
addChild(main_container);
thumbs = new Sprite();
thumbs.addEventListener(MouseEvent.CLICK, playVideo);
thumbs.addEventListener(MouseEvent.MOUSE_OVER, onOver);
thumbs.addEventListener(MouseEvent.MOUSE_OUT, onOut);
thumbs.x = thumbs_x;
thumbs.y = thumbs_y;
This is where the Issue is: (If i comment out this code it displays the thumbnails)
thumbs.width = thumb_width;
thumbs.height = (thumb_height + 11) * 3;
thumbs.buttonMode = true;
main_container.addChild(thumbs);
scrollbar = new UIScrollBar();
scrollbar.x = thumbs_x + thumb_width + 2;
scrollbar.y = thumbs_y;
scrollbar.setSize(25, (thumb_height + 11) * 3);
scrollbar.visible = true;
scrollbar.scrollTarget = thumbs;
main_container.addChild(scrollbar);
}
function callThumbs():void
{
for (var i:Number = 0; i (less than) numVideos; i++) //For some reason Stack Overflow isnt allowing me to put the symbol less than so i just typed it in...
{
var thumb_url = videoList[i].#thumb;
var thumb_loader = new Loader();
thumb_loader.name = i;
thumb_loader.load(new URLRequest(thumb_url));
thumb_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, thumbLoaded);
thumb_loader.y = (thumb_height + 11) * i;
}
}
function thumbLoaded(e:Event):void
{
var my_thumb:Loader = Loader(e.target.loader);
thumbs.addChild(my_thumb);
}
function playVideo(e:MouseEvent):void
{
setVideo(e.target.name);
}
function onOver (e:MouseEvent):void
{
var my_thumb:Loader = Loader(e.target);
my_thumb.alpha = 0.5;
}
function onOut (e:MouseEvent):void
{
var my_thumb:Loader = Loader (e.target);
my_thumb.alpha = 1;
}
function setVideo(current_Video)
{
var display:String = videoList[current_Video].#title;
var video:String = videoList[current_Video].#url;
txt_Display.text = display;
flvPlayer.source = video;
}
stop();
This is easy. You are creating Sprite, adding listeners, setting coordinates. The sprite is still empty. Then you set width and height, which are translating to scaleX and scaleY. On empty sprite this messes up transformation matrix and sprite will never show up. Set width, height, or scaleX/Y only on non-empty sprites.