Stroking rect background - pdfbox

I've recently updated PDFBox to version 2.0.0 (for its new images methods) but they've changed the way you fill a rect.
Previously you would addRect, set the stroking color and struck, set the non-stroking color and fill the rect.
Now the fillRect has been replaced with fill and I'm unable to stroke and fill. Calling stroking after filling will do nothing and vice-versa.
Now I'm forced to call addRect for a second time to get the desired effect.
Any help with updating my method?

Previously you would addRect, set the stroking color and struck
... and in doing so create an invalid PDF! Between the start of path creation (here: addRect) and its drawing (here: stroke), only additional path creation operations and eventually optionally a clipping path operation are allowed. Your setting the stroking color in-between is invalid.
Most PDF viewers don't complain about this invalid syntax but it is invalid nonetheless...
Now the fillRect has been replaced with fill and I'm unable to stroke and fill.
fillRect still is there and merely has been deprecated. Thus, you can look what it does:
public void fillRect(float x, float y, float width, float height) throws IOException
{
if (inTextMode)
{
throw new IllegalStateException("Error: fillRect is not allowed within a text block.");
}
addRect(x, y, width, height);
fill();
}
Thus, if you used to do
setStrokingColor(...);
addRect(...);
stroke();
setNonStrokingColor(...);
fillRect(...);
in PDFBox 1.8.x, you can do the same in 2.0.0 or (to not use deprecated methods) replace the last line by
addRect(...);
fill();
Now I'm forced to call addRect for a second time to get the desired effect.
But that is what you under the hood used to do before, too!
PS Recently two new operations have been added to PDFBox' PDPageContentStream class: fillAndStroke, fillAndStrokeEvenOdd, closeAndFillAndStroke, and closeAndFillAndStrokeEvenOdd. Thus, now you can also use
setStrokingColor(...);
setNonStrokingColor(...);
addRect(...);
fillAndStroke();

Related

GTK+3 render rectangle with selection background color

How is it possible to render a rectangle with the background color of selections in GTK+3. I cannot find any API to do that:
static gboolean draw_callback (GtkWidget *widget, cairo_t *cr, gpointer data)
{
auto state=reinterpret_cast<State*>(data);
auto width = gtk_widget_get_allocated_width (widget);
auto height = gtk_widget_get_allocated_height (widget);
auto context = gtk_widget_get_style_context (widget);
gtk_render_background(context,cr,0,0,width,height);
cairo_rectangle(cr,0,height*(1.0 - state->max),width,height*(state->max - state->min));
cairo_set_source_rgb(cr, 0.05,0.6,0.15); //What color should be used here?
cairo_fill (cr);
cairo_set_source_rgb(cr,0.01,0.3,0.07); //And here
auto mid=height*(1.0 - 0.5*(state->min + state->max));
cairo_move_to(cr,0, mid);
cairo_line_to(cr,width,mid);
cairo_stroke(cr);
return FALSE;
}
Use gtk_render_frame() and gtk_render_background(), and set up the GtkStyleContext you obtain from the GtkWidget instance with the CSS state you want to replicate.
If you want to adhere to the theme, then you cannot draw yourself; and CSS does not have "colors": each CSS state can have multiple layers that include images, gradients, and complex blend modes.
Well, here is my hack:
ColorRGBA get_ambient_color(GtkWidget* widget)
{
auto surface=cairo_image_surface_create(CAIRO_FORMAT_ARGB32,4,4);
auto cr=cairo_create(surface);
while(widge!=NULL)
{
auto context=gtk_widget_get_style_context(widget));
gtk_render_background(context,cr,0,0,1,1);
cairo_surface_flush(surface);
auto content=cairo_image_surface_get_data(surface);
if(content[3]==255)
{
auto ret=ColorRGBA{content[2]/255.0f,content[1]/255.0f,content[0]/255.0f,content[3]/255.0f};
cairo_destroy(cr);
cairo_surface_destroy(surface);
return ret;
}
// Surface is not opaque yet. Continue to parent container.
widget_handle=gtk_widget_get_parent(GTK_WIDGET(widget_handle));
}
cairo_destroy(cr);
cairo_surface_destroy(surface);
return ColorRGBA{1.0f,1.0f,1.0f,1.0f};
}
It seams that I have failed to convince people, why you need the ambient colour, so here are two use-cases:
Determine if we are using a dark/light theme. For some applications, this is sufficient. Querying the state only works if the theme supports dark/light modes. This proves the actual result.
Use as input colour for simulating global illumination. The shading of widgets should be affected by the ambient, hence the name. Another good name would be get_average_background. Themers: please don't use gradients with high contrast.
Case 1: A plot
Now you say that the colour of cursors and function graphs should be themable. That is simply not possible: The user of this plot widget can add as many curves and cursors as he wishes, and the easiest way to differentiate them is to use distinct colours.
What about curve and cursor lightness? If the background is dark, then the curve should be light and vice versa. And what background should be chosen? Ideally, something close the the background of the parent widget, but if the theme is regular, white for light, and black for dark would work. Do you notice that the curves are darker in the second figure?
Case 2: A checkbox that looks like a metallic toggle switch button
With the following technique, I have created a switch that looks exactly as if it were rendered through the Cycles path tracer. This is implemented in Gtk+2, but the algorithm is the same.
The two input images
The code
GtkAllocation alloc;
gtk_widget_get_allocation(widget,&alloc);
auto width=alloc.width;
auto context=CairoContext( gdk_cairo_create(gtk_widget_get_window(widget)) );
auto w_in=cairo_image_surface_get_width(light);
auto h_in=cairo_image_surface_get_height(light);
// Render direct lighting
auto surf_temp=CairoSurface( cairo_image_surface_create(CAIRO_FORMAT_ARGB32,w_in,h_in) );
auto context_temp=CairoContext( cairo_create(surf_temp) );
cairo_set_source_surface(context_temp,light,0,0);
cairo_set_operator(context_temp,CAIRO_OPERATOR_OVER);
cairo_paint(context_temp);
//Render ambient reflections
auto surf_temp_2=CairoSurface( cairo_image_surface_create(CAIRO_FORMAT_ARGB32,w_in,h_in) );
auto context_temp_2=CairoContext( cairo_create(surf_temp_2) );
cairo_set_source_surface(context_temp_2,background,0,0);
cairo_set_operator(context_temp_2,CAIRO_OPERATOR_OVER);
cairo_paint(context_temp_2);
cairo_set_operator(context_temp_2,CAIRO_OPERATOR_MULTIPLY);
//Multiply reflections with the background color
cairo_set_source_rgb(context_temp_2, color_bg.r, color_bg.g, color_bg.b);
cairo_rectangle(context_temp_2, 0, 0, w_in, h_in);
cairo_mask_surface(context_temp_2,surf_temp,0,0);
//Add the results
cairo_set_source_surface(context_temp,surf_temp_2,0,0);
cairo_set_operator(context_temp,CAIRO_OPERATOR_ADD);
cairo_mask_surface(context_temp,surf_temp,0,0);
//Scale and move things into place
auto s=static_cast<double>(width)/static_cast<double>(w_in);
cairo_translate(context,alloc.x,alloc.y);
cairo_scale(context,s,s);
cairo_set_source_surface(context,surf_temp,0,0);
cairo_set_operator(context,CAIRO_OPERATOR_OVER);
cairo_paint(context);
Thoughts
The first example boils down to a light/dark query which is currently missing. Maybe querying colours is not required for this to work, but then there has to be an API controlling the shape and blending mode when rendering the background. For example, to render the ambient reflection, I use multiply rather than over. Also, gtk_render_background appears to be a no-op, since GtkDrawingArea has zero opacity (that's why I needed the loop). To be useful, it must use the background as it appears on screen, not the background of the current widget.

change CAMetalLayer background color

My CAMetalLayer background color is black, even if i'm assigning new color as the backgroundColor property.
Am i missing something? Thanks!
Link to the original project :
https://github.com/audiokit/MetalParticles
This project takes a rather unconventional approach to clearing the drawable's texture each frame: it replaces the textures contents with an array of zeros that is the same size as the texture (width * height * 4). Subsequently, it encodes some compute work that actually draws the particles. This is almost certainly not the most efficient way to achieve this effect, but if you want to make the smallest change that could possibly work (as opposed to experimenting with making the code as efficient as possible), Just fill the blankBitmapRawData array with your desired clear color (near line 82 of ParticleLab.swift).
I have gone through your code and can not see a place where you are setting background Color.
The metal layer is added as a sublayer to it, so you have to set it explicitly.
Add this line at the end of your init method in ParticialLab class and see if it works.
self.backgroundColor = UIColor.redColor().CGColor
I found that self.isOpaque = false was needed on the layer.

JSX (Photoshop) - document resolution in dpi

I'm working with a jsx script in Photoshop that resizes images to a specific size. The resolution is set at 200 dpi. After running the script, I can check this under Image > Image Size.
Problem is, depending on the image, it initially tends to show the resolution in dots/cm instead of dots/inch. The number itself is correct either way, but I'd like to see it mentioned there as the latter. Is there a way to realize this in JSX?
Thanks!
J
The easy way is to open your Info Panel by going to Window > Info, and then click on the x/y coordinates dropdown in the Info Panel and select inches. The dropdown is the + toward the lower-left of the panel, with the little down arrow at the bottom right of the + symbol (The plus is actually an x axis and y axis representing a coordinate plane). After that, when you check under Image > Image Size, it should show you all information in inches instead of centimeters. This should also show you inches anywhere else you look in Photoshop's interface, too, such as the rulers.
An exception would be that when using selection tools, such as the marquee tool with a setting like "fixed size" selected, you can override the units setting by typing in another unit in the Width and Height sections at the top of the window. You can even mix and match units, making a precise selection that is, for example, exactly 250 pixels (px in the Width setting) by 30 points (pt in the Height setting). And when you check your image size, it should still show you results in inches.
And finally, to answer your question as it was asked, the following code will change your rulerUnits preference without opening the Info Panel.
#target Photoshop
preferences.rulerUnits = Units.INCHES;
Note that if you want to write other scripts, you can change the rulerUnits to whatever units the script calls for, and then at the end of the script put your units back the way you had them.
#target Photoshop
// Save the original rulerUnits setting to a variable
var originalRulerUnits = preferences.rulerUnits;
// Change the rulerUnits to Inches
preferences.rulerUnits = Units.INCHES;
//
// Do magical scripty stuff here...
//
// Restore the original setting
preferences.rulerUnits = originalRulerUnits;
// List of rulerUnits settings available
// Units.CM
// Units.INCHES
// Units.MM
// Units.PERCENT
// Units.PICAS
// Units.PIXELS
// Units.POINTS

How to correctly paint a huge image

I'm fairly new to wxWidgets so please bear with me. Let's say I have a 10Kx10K image and my wxScrolledWindow has a size of 640x480. I load the whole image into a wxBitmap which I use in my paint function.
Now in my OnPaint function I just say
wxPaintDC dc(this);
dc.DrawBitmap(_Bitmap, 0, 0 );
This somewhat works for the first few paints but soon the Window content is out order and artifacts appear. This happens very fast when I move a scroll bar back and forth very quickly.
I use the latest wxWidgets on a Windows 7 machine.
So, how can I improve my painting code?
Many thanks,
Christian
Using a 10000x10000 wxBitmap is a bad idea on its own, it may simply fail to be created on an older system (that's 400MiB of video RAM!). Drawing it entirely is sheer madness.
I don't know where does your data come from but in a typical case of e.g. a map to be shown on screen, you should break it into tiles, convert the tiles that are currently visible on screen to wxBitmap (or several of them) and draw only those.
Then you may optimize your drawing by using double buffering (which is relatively useless under Windows 7 that double buffers everything on its own) and otherwise, but you should be using a reasonably-sized backing store bitmap.
This sounds like something that might be helped by using double buffering.
The first thing to start trying is to replace wxPaintDC with wxBufferedPaintDC
For more suggestions, here is a wiki article on the subject: http://wiki.wxwidgets.org/Flicker-Free_Drawing
As Ravenspoint kindly pointed out, there is an article on wxWidgets' wiki. So according to that article two things need to happen. First override the EVT_ERASE_BACKGROUND with an empty function.
void Canvas::EraseBackground( wxEraseEvent& WXUNUSED(event))
{
}
And second to implement a basic double buffering scheme. Here is how I did it.
void Canvas::OnPaint(wxPaintEvent& WXUNUSED(event))
{
int x, y;
GetViewStart(&x, &y);
wxRect Client_Area = GetClientRect();
int width = Client_Area.width;
int height = Client_Area.height;
wxBitmap Current = _Bitmap.GetSubBitmap(wxRect( x * 10, y * 10, width, height ));
wxPaintDC dc(this);
dc.DrawBitmap(Current, 0, 0, false );
}
My scroll rate for both x and y is set to 10. That's why I multiply the view start coordinates.
Any more insight is very welcome.
Thanks,
Christian

can we resize the tab size in wxnotebook?

I'm using wxwidgets under linux environment and using wxnotebook in a frame.
I have four tabs (left side of frame) in frame and want to resize their size i.e change their width and length of tab only. I used SetTabSize() but it is not working.
I want to change their width but don't know how.
wxNotebook::SetPadding
void SetPadding(const wxSize& padding)
Sets the amount of space around each page's icon and label, in pixels.
NB: The vertical padding cannot be changed in wxGTK.
It looks like this is a Windows only feature.
From: notebook.h
// Windows-only at present. Also, you must use the wxNB_FIXEDWIDTH
// style.
void SetTabSize(const wxSize& sz) wxOVERRIDE;