Pyglet: why does the text in my example become fuzzy when I resize the window? - pyglet

In the following toy example, I have a text layout in a resize-able window. When the window is re-sized, the text becomes fuzzy for some resolutions (give it a try). Why is that?
import pyglet
width, height = 500, 500
window = pyglet.window.Window(width, height, resizable=True)
batch = pyglet.graphics.Batch()
document = pyglet.text.document.FormattedDocument()
document.insert_text(0, 'Hello world!', attributes=dict(font_name='Arial', font_size=12, color=(255, 255, 255, 255)))
layout = pyglet.text.layout.IncrementalTextLayout(document, width, height, multiline=True, batch=batch)
# for drawing graphics
pyglet.gl.glLineWidth(3)
outline = batch.add(4, pyglet.gl.GL_LINE_LOOP, None, ('v2f', (0, 0, width, 0, width, height, 0, height)), ('c4B', (255, 0, 0, 0)*4))
#window.event
def on_resize(width, height):
document.delete_text(0, len(document.text))
document.insert_text(0, "Layout has been resized to {}x{}".format(0.9*width, 0.9*height))
layout.width = 0.9*width
layout.height = 0.9*height
layout.x = (width - layout.width)*0.5
layout.y = (height - layout.height)*0.5
outline.vertices = (layout.x, layout.y, layout.width + layout.x, layout.y, layout.width + layout.x, layout.height + layout.y, layout.x, layout.height + layout.y)
#window.event
def on_draw():
window.clear()
batch.draw()
pyglet.app.run()

Things start to become wonky because the layout is being given decimal width and height. Fixing that removes the fuzzy text issues:
import pyglet
width, height = 500, 500
window = pyglet.window.Window(width, height, resizable=True)
batch = pyglet.graphics.Batch()
document = pyglet.text.document.FormattedDocument()
document.insert_text(0, 'Hello world!', attributes=dict(font_name='Arial', font_size=12, color=(255, 255, 255, 255)))
layout = pyglet.text.layout.IncrementalTextLayout(document, width, height, multiline=True, batch=batch)
# for drawing graphics
pyglet.gl.glLineWidth(3)
outline = batch.add(4, pyglet.gl.GL_LINE_LOOP, None, ('v2f', (0, 0, width, 0, width, height, 0, height)), ('c4B', (255, 0, 0, 0)*4))
#window.event
def on_resize(width, height):
width, height = int(width), int(height)
window.set_size(width, height)
layout_width, layout_height = int(0.9*width), int(0.9*height)
document.delete_text(0, len(document.text))
document.insert_text(0, "Layout has been resized to {}x{}".format(layout_width, layout_height))
layout.width, layout.height = layout_width, layout_height
layout.x = int((width - layout_width)*0.5)
layout.y = int((height - layout_height)*0.5)
outline.vertices = (layout.x, layout.y, layout.width + layout.x, layout.y, layout.width + layout.x, layout.height + layout.y, layout.x, layout.height + layout.y)
#window.event
def on_draw():
window.clear()
batch.draw()
pyglet.app.run()

I had the same problem and I made it work like this:
You will need a wrapper class which will have the on_resize event handler. Also it needs the parent window.
class Label(pyglet.text.Label):
def __init__(self, window,**kwargs):
self.window = window
self.window.push_handlers(self)
self.init_settings = dict()
for k,v in kwargs.items():
if callable(v):
kwargs[k] = v(self.window)
self.init_settings[k] = v
super().__init__(**kwargs)
def on_resize(self, width, height):
for k,v in self.init_settings.items():
setattr(self,k,v(self.window))
Usage:
Each property you need to update on resizing the window will be a lambda function. Here you should write the initial values of the label with the initial window sizes.
class WindowSubclass(pyglet.window.Window):
def __init__(self,*args,**kwargs):
self.initial_size = self.width,self.height
self.label = Label(window=self,
text='PAUSED',
multiline=False,
font_name='Times New Roman',
bold=True,
font_size=lambda win:24*win.height/win.initial_height,
width=lambda win:win.width/4,
x=lambda win:win.width/2,
y=lambda win:win.height/2,
color=(255, 255, 255, 255),
anchor_x='center', anchor_y='center')

Related

Will pyglet draw a line at y = 0?

windows 10/pyglet 1.5.26.
I'm unable to convince pyglet to draw a (visible) line with both vertices having a y-coordinate = 0. This does not seem to be a problem with other primitives:
from pyglet import shapes
class DrawingWindow(pyglet.window.Window):
def __init__(self):
super(DrawingWindow, self).__init__(300, 300)
self.batch = pyglet.graphics.Batch()
def on_draw(self):
# this red line is not visible:
l0 = shapes.Line(0, 0, 300, 0, color=(255, 0, 0), batch=self.batch)
# this blue one is (note y-coordinate), though it appears to have y-coordinates = 0:
l1 = shapes.Line(0, 1, 200, 0, color=(0, 0, 255), batch=self.batch)
# and this green-bordered rectangle is OK too:
square = shapes.BorderedRectangle(0, 0, 100, 100,
border=1, color=(255, 255, 255),
border_color=(0, 255, 0), batch=self.batch)
self.clear()
self.batch.draw()
if __name__ == '__main__':
window = DrawingWindow()
pyglet.app.run()```
I've tried this with a simple pyglet.draw(...) call with the same result.

tm_compass does not appear inside of graph

I'm trying to make a map of Europe using tmap and the eurostat package.
I want to add a compass and a scale bar to the map. However they don't appear inside the graph, but outside of the map, at the bottom. Does anyone know what I'm doing wrong? I want the compass at the left top of the map, and the scale bar at the right bottom.
countries = gisco_get_countries(
year = "2016",
epsg = "3035",
resolution = "3"
)
br = c(0,40,50,65,80,150)
tm_shape(countries, bbox = c(23, 14, 74, 55) * 10e4) +
tm_fill("#E0E0E0") +
tm_shape(nuts2.sf) +
tm_fill(
"fatal_inj_30day",
breaks = br,
style = "fixed",
palette = "Blues",
alpha = .7,
title = "Fatalities per million inhabitants \n(2018-2019)"
) +
tm_compass(position = c("left","top")) +
tm_scale_bar(position = c("right","bottom")) +
tm_shape(countries) +
tm_borders(lwd = .25) +
tm_layout(
bg.color = "#F2F2F2",
outer.bg.color = "white",
legend.bg.color = "white",
legend.frame = "black",
legend.title.size = 0.8,
inner.margins = c(0, 0, 0, 0),
outer.margins = c(0, 0, 0, 0),
frame = TRUE,
frame.lwd = 0,
attr.outside = TRUE,
legend.position = c("right", "top"),
main.title = "Note: regions with 10 fatalities or less are not included in the Figure",
main.title.position = "left",
main.title.size = 0.7
)

ItextSharp - Add text watermark on separate lines

I am trying to add a watermak on a pdf file with itextsharp 5.1.2.0 .
I want the watermark to be in the center of the page, with a 45° angle, with a border around these lines.
Here is my code :
for (int i = 1; i <= reader.NumberOfPages; i++)
{
iTextSharp.text.Rectangle pageSize = reader.GetPageSizeWithRotation(i);
PdfContentByte pdfPageContents;
pdfPageContents = pdfStamper.GetOverContent(i);
pdfPageContents.BeginText();
PdfGState gstate = new PdfGState();
gstate.FillOpacity = 0.4f;
gstate.StrokeOpacity = 0.4f;
pdfPageContents.SaveState();
pdfPageContents.SetGState(gstate);
BaseFont baseFont = BaseFont.CreateFont(BaseFont.HELVETICA_BOLD, Encoding.ASCII.EncodingName, false);
pdfPageContents.SetRGBColorFill(255, 0, 0);
double radians = Math.Atan2(pageSize.Height, pageSize.Width);
float textAngle = radians * (180 / Math.PI);
pdfPageContents.ShowTextAligned(PdfContentByte.ALIGN_CENTER, "Phrase 1 This is Phrase 2 and must be centered below phrase 1" , pageSize.Width / 2, pageSize.Height / 2, textAngle);
//pdfPageContents.ShowTextAligned(PdfContentByte.ALIGN_CENTER, "Phrase 1", pageSize.Width / 2, pageSize.Height / 2, textAngle);
//pdfPageContents.ShowTextAligned(PdfContentByte.ALIGN_CENTER, "This is Phrase 2 and must be centered below phrase 1", pageSize.Width / 2 + 20 , pageSize.Height / 2 - 20, textAngle);
}
This adds the watermark on one line.
I am able to have two lines with the commented code.
What i dont like are the hardcoded values for the position for the second line.
I am sure there must be a better way of achieving this.
Regarding the border i did not manage to add it around the lines.
If someone can help me with this case .
Thanks
basically what I do for my project is as under... here font_size and style are the variables... also llx, lly, urx,ury are variable for the the corrdinates position and size.. in alignment variable, you can set the alignment easily....
for opacity your code will work fine(you can add state options)
Dim Font = New Font(arial, FONT_SIZE, STYLE, iTextSharp.text.Color.BLACK )
dim text = GetRowValue(row, "CONTROL_MAP")
Dim ct As ColumnText = New ColumnText(pdf_cb)
ct.SetSimpleColumn(LLX, LLY, URX, URY, FONT_SIZE, ALIGNMENT)
ct.SetText(New Paragraph(0, text, Font))
ct.Go()

MyHDL: Can't translating Signal.intbv.max to VHDL

I'm new to python and MyHDL so I started by converting old VHDL projects to MyHDL. This project is a vga timer that can accept any width, height, and frequency (given that they actually work with monitors). It doesn't successfully convert to either VHDL or Verilog because of the statements:
h_count.val.max # line 30
v_count.val.max # line 33
I can print their values just fine so they definitely evaluate to integers, but if I replace them with their literal values then it properly converts. I couldn't find anything about this in the myhdl issue tracker, but I don't want to add a false issue because of a newbie's mistake. Is there a proper way to use Signal.val.max or do I just avoid it? Here's the full code:
from myhdl import Signal, intbv, always_comb, always, toVHDL
def vga_timer(clk, x, y, h_sync, v_sync, vidon, width=800, height=600, frequency=72,
left_buffer=0, right_buffer=0, top_buffer=0, bottom_buffer=0):
# load vga constants by resolution
resolution = (width, height, frequency)
supported_resolutions = {(640, 480, 60): (16, 96, 48, 10, 2, 33, 0),
(800, 600, 60): (40, 128, 88, 1, 4, 23, 1),
(800, 600, 72): (56, 120, 64, 37, 6, 23, 1),
(1024, 768, 60): (24, 136, 160, 3, 6, 29, 0),
(1280, 720, 60): (72, 80, 216, 3, 5, 22, 1),
(1920, 1080, 60): (88, 44, 148, 4, 5, 36, 1)}
assert resolution in supported_resolutions, "%ix%i # %ifps not a supported resolution" % (width, height, frequency)
screen_constants = supported_resolutions.get(resolution)
# h for horizontal variables and signals, v for vertical constants and signals
h_front_porch, h_sync_width, h_back_porch, v_front_porch, v_sync_width, v_back_porch, polarity = screen_constants
h_count = Signal(intbv(0, 0, width + h_front_porch + h_sync_width + h_back_porch))
v_count = Signal(intbv(0, 0, height + v_front_porch + v_sync_width + v_back_porch))
print(h_count.val.max)
print(v_count.val.max)
#always(clk.posedge)
def counters():
h_count.next = h_count + 1
v_count.next = v_count
if h_count == 1040 - 1: # h_count.val.max - 1:
h_count.next = 0
v_count.next = v_count + 1
if v_count == 666 - 1: # v_count.val.max - 1:
v_count.next = 0
# determines h_sync and v_sync
#always_comb
def sync_pulses():
h_sync_left = width - left_buffer + h_front_porch
h_sync_right = h_sync_left + h_sync_width
h_sync.next = polarity
if h_sync_left <= h_count and h_count < h_sync_right:
h_sync.next = not polarity
v_sync_left = height - top_buffer + v_front_porch
v_sync_right = v_sync_left + v_sync_width
v_sync.next = polarity
if v_sync_left <= v_count and v_count < v_sync_right:
v_sync.next = not polarity
#always_comb
def blanking():
vidon.next = 0
if h_count < width - left_buffer - right_buffer and v_count < height - top_buffer - bottom_buffer:
vidon.next = 1
#always_comb
def x_y_adjust():
# x and y are only used when vidon = 1. during this time x = h_count and y = v_count
x.next = h_count[len(x.val):]
y.next = v_count[len(y.val):]
return counters, sync_pulses, blanking, x_y_adjust
width = 800
height = 600
frequency = 72
clk = Signal(bool(0))
x = Signal(intbv(0)[(width-1).bit_length():])
y = Signal(intbv(0)[(height-1).bit_length():])
h_sync = Signal(bool(0))
v_sync = Signal(bool(0))
vidon = Signal(bool(0))
vga_timer_inst = toVHDL(vga_timer, clk, x, y, h_sync, v_sync, vidon, width, height, frequency)
Any miscellaneous advice on my code is also welcome.
You may have found this out by now, but if you want convertible code, you can't use the signal qualities (min, max, number of bits, etc.) in the combinational or sequential blocks. You can use them in constant assignments outside these blocks, though. So if you put these instead of your print statements:
h_counter_max = h_count.val.max - 1
v_counter_max = v_count.val.max - 1
you can use h_counter_max and v_counter_max in your tests on line 30 and 33.
The min, max attributes can be used in the latest version.

The page margin and the start of the paragraph are not match in ITextsharp

I am using Itextsharp.
doc.SetMargins(36, 36, 36, 36);
doc.NewPage();
writer.PageEvent = new PDFPageEvent();
int horizontalMarginForColumn = 54;
int bottomMarginForColumn = 72;
int topMarginForColumn = 112;
int interval = 8;
Rectangle pageNumberLeftLocation = new Rectangle(horizontalMarginForColumn, doc.PageSize.Height - 36, horizontalMarginForColumn + 36, doc.PageSize.Height);
paragraph = new Paragraph();
paragraph.SpacingBefore = 0;
paragraph.Alignment = Element.ALIGN_LEFT;
line = new LineSeparator(1f, 100f, BaseColor.BLACK, 0, 0f);
line.Alignment = Element.ALIGN_CENTER;
paragraph.Add(new Chunk(line));
paragraph.Add(Chunk.NEWLINE);
chunk = new Chunk(" Index", FontFactory.GetFont("Arial", 15, Font.BOLD));
chunk.setLineHeight(23);
paragraph.Add(chunk);
paragraph.Add(Chunk.NEWLINE);
paragraph.Add(new Chunk(line));
doc.Add(paragraph);
writer.DirectContent.SetColorStroke(BaseColor.BLUE);
writer.DirectContent.Rectangle(pageNumberLeftLocation.Left, pageNumberLeftLocation.Bottom, pageNumberLeftLocation.Width, pageNumberLeftLocation.Height);
writer.DirectContent.Stroke();
The top margin of the page is 36, and the height of the rectangle is 36. So I assume that the bottom line of the rectangle and the beginning of the paragraph which is a black line, sholud be in the same vertical position. But you can see, there is some space between the two. Why is this? Thank you.