Reportlab pdfgen support for bold truetype fonts - django

I have been using reportlab pdfgen to create dynamic pdf documents for printing. It has been working very well for a number of years.
We are having a fund raising event coming up, and wish to generate pdf receipts with the 'theme' font we are using (specifically talldeco.ttf).
I have set the font no problem using the following:
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
ttfFile = "/usr/share/fonts/truetype/ttf-tall-deco/TALLDECO.TTF"
pdfmetrics.registerFont(TTFont("TallDeco", ttfFile))
p.setFont("TallDeco", 18) # Was Times-Bold...
Now comes the issue: some of the text needs to be bold and italics, and the talldeco just comes with 1 file (unlike some of the other fonts). I can bold and italicize text in this font in openoffice.
Per the reportlab users guide (http://www.reportlab.com/software/opensource/rl-toolkit/guide/) page 53, it should be possible and they show some code and the results, but our software is using drawString calls instead of paragraphs. A test app based on the sample noted above:
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.pdfbase.pdfmetrics import registerFontFamily
ttfFile = "/usr/share/fonts/truetype/ttf-tall-deco/TALLDECO.TTF"
pdfmetrics.registerFont(TTFont("TallDeco", ttfFile))
registerFontFamily('TallDeco',normal='TallDeco',bold='TallDeco-Bold',italic='TallDeco-Italic',boldItalic='TallDeco-BoldItalic')
p.setFont("TallDeco-Bold", 18) # Was Times-Bold...
Just gives a Key Error on 'TallDeco-Bold'.
Any suggestions?

TTFont has a subfontIndex parameter.
The following works for me (using reportlab 3.0 on OS X):
menlo_path = "/System/Library/Fonts/Menlo.ttc"
pdfmetrics.registerFont(ttfonts.TTFont("Menlo", menlo_path,
subfontIndex=0))
pdfmetrics.registerFont(ttfonts.TTFont("Menlo-Bold", menlo_path,
subfontIndex=1))
pdfmetrics.registerFont(ttfonts.TTFont("Menlo-Italic", menlo_path,
subfontIndex=2))
pdfmetrics.registerFont(ttfonts.TTFont("Menlo-BoldItalic", menlo_path,
subfontIndex=3))
pdfmetrics.registerFontFamily("Menlo", normal="Menlo", bold="Menlo-Bold",
italic="Menlo-Italic",
boldItalic="Menlo-boldItalic")

The bold, italic and boldItalic fonts need to be defined.
pdfmetrics.registerFont(TTFont("TallDeco-Bold", ttfFile))
pdfmetrics.registerFont(TTFont("TallDeco-Italic", ttfFile))
pdfmetrics.registerFont(TTFont("TallDeco-BoldItalic", ttfFile))
But because they all point to the same ttfFile the output will all look like the default TallDeco i.e. no bold or italic

Related

How to Read the Barcode in image using Python 3.6 without using Zbar

I am New to Barcode Reader i found some Tutorial about Zbar and which seems to not support in ZBAR. I like to raed the Barcode in a Image and extract the Data in it.
This is What is Actually Tried.
def detect_barcode(request):
try:
import pyqrcode
import zbarlight
qr = pyqrcode.create("HORN O.K. PLEASE.")
qr.png("download.png", scale=6)
import qrtools
from qrtools.qrtools import QR
from qrtools.qrtools import Image,BOM_UTF8
qr = qrtools.QR()
qr.decode("download.png")
True
print(qr.data);
qr.data
except Exception as e:
test = str(e)
I Need to Decode the Barcode and extract the Data. I don't like to use Zbar.
If it helps. We have a web browser that reads barcodes. No changes to your page are needed.
You can embed barcode scanning in your page and handle the result with JavaScript if you need more control.
Scan to Web

Text Encoding Between Python File, Maya Script Editor, and Maya UI (Python 2.7, Maya 2015, Windows 7)

I've got a python file that I'm loading as a script into the maya script editor. The python file is currently encoded as UTF-8.
I have the need to use the ↑ and ↓ characters (or any other arrow substitutes within Unicode, such as ➘ or ➚, I just want to convey up and down). I'm using the characters as the label of a button. Here's the script:
import Maya.cmds as cmds
def initInterface():
cmds.window("mywin")
cmds.rowColumnLayout("my_rcl", nc=1)
cmds.button(label=u'\↑')
cmds.button(label=u'\↓')
cmds.showWindow("mywin")
initInterface()
The script is saved as myPythonScript.py and is then loaded into the Maya script editor using the load script button.
On execution, I get a UI window and buttons as expected, but the labels for the buttons are now "?" (question marks). I can't seem to get Maya to display the arrows.
To solve this, I've tried a couple of in-code things. Here are a few of my attempts:
# Attempt 1
upArrow = u'\↑'
upArrowEncoded = upArrow.encode("utf-8")
cmds.button(label=upArrowEncoded)
# Result: "?"
# Attempt 2
upArrow = u'\U+2B06'
cmds.button(label=upArrow)
# Result: "?B06"
# Attempt 3
upArrow = u'\U+2B06'
upArrowEncoded = upArrow.encode("utf-8")
cmds.button(label=upArrowEncoded)
# Result: "?"
To be honest (and is likely to be apparent from my code snippets) I've never experimented with text encoding and know next to nothing about it. I'm not sure if I need to change the encoding of my .py file, or encode the string with UTF-16 or something. This is way outside of my area of expertise and I'm having a hard time finding resources to help me understand text and string encoding.
I did check out this:
Unicode Within Maya
And this:
Convert a Unicode String to a String in Python Containing Extra Symbols
But I wasn't able to understand a lot of what I read, and I'm not sure if they relate to this issue or not.
I'm the type of person who doesn't enjoy using code I don't understand (how do people even document that?), so I'm here to ask for links to learning resources and for general advice on the subject, moreso than for a code snippet that does what I want. If it turns out this is not possible, I can use image buttons instead. But they are less efficient and time consuming to produce for each special character I may use.
Thank you for reading through this, and thank you in advance to anyone who can point me in the right direction here. Cheers!
As far as I can tell, the native MayaUi uses/has access to the Code Page 1252 Windows Latin 1 (ANSI) character set (at least on Windows...) as mentioned here, and after some noodling these *all appear to work as advertised.
I'd be curious to see an answer that explained how to change that and access what OP is looking for, but as an alternative to anyone that really truly wants more special characters, may I suggest learning PySide / Qt for building your UI.
Caveats
A lot more boilerplate and setup when it comes to making 'something simple'
Several mayaControls do not have direct Qt implementations (gradientControlNoAttr being a recent discovery, and case in point)
Example is written under the assumption that user has installed and uses Qt.py
Lets dive right in:
import maya.cmds as cmds
import maya.OpenMayaUI as omui
from Qt import QtCore, QtGui
from Qt.QtWidgets import *
from shiboken import wrapInstance
def maya_main_window():
main_window_ptr = omui.MQtUtil.mainWindow()
return wrapInstance(long(main_window_ptr), QWidget)
class TestUi(QDialog):
def __init__(self, parent=maya_main_window()):
super(TestUi, self).__init__(parent)
self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
def create(self):
self.setWindowTitle("TestUi : Unicode")
self.setWindowFlags(QtCore.Qt.Tool)
self.create_controls()
self.create_layout()
self.create_connections()
def create_controls(self):
"""
Create the widgets for the dialog.
"""
# using "Python source code" unicode values
# ie: https://www.fileformat.info/info/unicode/char/2191/index.htm
self.up_button = QPushButton(u'\u2191')
self.down_button = QPushButton(u'\u2193')
self.left_button = QPushButton(u'\u2190')
self.right_button = QPushButton(u'\u2192')
def create_layout(self):
"""
Create the layouts & add widgets
"""
main_layout = QVBoxLayout()
main_layout.setContentsMargins(6, 6, 6, 6)
main_layout.addWidget(self.up_button)
main_layout.addWidget(self.down_button)
main_layout.addWidget(self.left_button)
main_layout.addWidget(self.right_button)
main_layout.addStretch()
self.setLayout(main_layout)
def create_connections(self):
"""
Create the signal/slot connections
"""
self.up_button.clicked.connect(self.on_button_pressed)
self.down_button.clicked.connect(self.on_button_pressed)
self.left_button.clicked.connect(self.on_button_pressed)
self.right_button.clicked.connect(self.on_button_pressed)
def on_button_pressed(self):
print "Button Pressed"
def LaunchUI():
if __name__ == "__main__":
# Development workaround for PySide winEvent error (Maya 2014)
# Make sure the UI is deleted before recreating
try:
test_ui.deleteLater()
test_ui.close()
except:
pass
# Create minimal UI object
test_ui = TestUi()
# Delete the UI if errors occur to avoid causing winEvent
# and event errors (in Maya 2014)
try:
test_ui.create()
test_ui.show()
except:
test_ui.deleteLater()
traceback.print_exc()
LaunchUI()
There's an awful lot to unpack there for not a terribly huge payoff, but the relevant piece of information is living under "create_controls".

pyPdf Splitting Large PDF fails after splitting 150-152 pages of the PDF

I have a function that takes in PDF file path as input and splits it into separate pages as shown below:
import os,time
from pyPdf import PdfFileReader, PdfFileWriter
def split_pages(file_path):
print("Splitting the PDF")
temp_path = os.path.join(os.path.abspath(__file__), "temp_"+str(int(time.time())))
if not os.path.exists(temp_path):
os.makedirs(temp_path)
inputpdf = PdfFileReader(open(file_path, "rb"))
if inputpdf.getIsEncrypted():
inputpdf.decrypt('')
for i in xrange(inputpdf.numPages):
output = PdfFileWriter()
output.addPage(inputpdf.getPage(i))
with open(os.path.join(temp_path,'%s.pdf'% i),"wb") as outputStream:
output.write(outputStream)
It works for small files but the problem is that It only splits for first 0-151 pages when the PDF has more than 152 pages and stops after that. It also sucks out all the memory of the system before I kill it.
Please let me know what I'm doing wrong or where the problem is occurring and how do I correct it?
It seems like the problem is with pyPdf itself. I switched to pyPDF2 and it worked.

Dynamically change the shape of bokeh Figure

I am building a web app that will display images as part of a data analysis pipeline. For this, I need to dynamically change the width and height of a Figure object in bokeh.
With the following code, the shape of the Figure is changed, but the change only takes effect after I resize my browser window, even if the browser window resize is ever so small.
import bokeh.plotting
import bokeh.models
import bokeh.layouts
# set up the interface
fig1 = bokeh.plotting.figure()
button = bokeh.models.Button(label='scramble')
# define a callback and connect it
def callback():
fig1.width = int(fig1.width * .8)
button.on_click(callback)
# add everything to the document
bokeh.plotting.curdoc().add_root(bokeh.layouts.column(button, fig1))
Is there some update method which I need to run? I have read about "next tick callbacks" but I don't understand if that is relevant.
The above behavior occurs both with firefox and chromium on my gnome system.
The reason this is happening is because the layout is not getting updated. Although your code changes the figure's property value you have to recompute all values in the Document solver for an actual resize to happen.
Here is the line in BokehJS where the resize hook happens:
https://github.com/bokeh/bokeh/blob/master/bokehjs/src/coffee/document.coffee#L92
After resize is called at the document level, resize objects re-render:
https://github.com/bokeh/bokeh/blob/master/bokehjs/src/coffee/models/layouts/layout_dom.coffee#L61
The problem is that there's not currently, to the best of my knowledge, an exposed way to re-trigger the document resize event.
However you can do it client side. Here's working code using CustomJS:
test.py
from bokeh.io import show
from bokeh.layouts import column
from bokeh.models import Button, CustomJS
from bokeh.plotting import figure
fig = figure()
button = Button(label='scramble')
button.callback = CustomJS(args=dict(fig=fig), code="""
var old_width = fig.width;
var doc = fig.document;
fig.width = old_width * 0.8;
doc.resize();
""")
col = column(button, fig)
show(col)
This can be run with python test.py.
Note you could also do this with bokeh server replacing the last line show(col) with curdoc().add_root(col), but I didn't do that to emphasize that this is a client-side solution.
There is a way to dynamically resize bokeh charts with built in functionality. For example,
fig = plotting.figure(width=1200, height=900, title="Dynamic plot".format(chartType), sizing_mode='scale_width')
The key option being sizing_mode='scale_width'
The width and height commands serve as initial values. There are other options for sizing_mode so I would look into that.

Read multilanguage strings from html via Python 2.7

I am new in python 2.7 and I am trying to extract some info from html files. More specifically, I wand to read some text information that contains multilanguage information. I give my script hopping to make things more clear.
import urllib2
import BeautifulSoup
url = 'http://www.bbc.co.uk/zhongwen/simp/'
page = urllib2.urlopen(url).read().decode("utf-8")
dom = BeautifulSoup.BeautifulSoup(page)
data = dom.findAll('meta', {'name' : 'keywords'})
print data[0]['content'].encode("utf-8")
the result I am taking is
BBCϊ╕φόΨΘύ╜ΣΎ╝Νϊ╕╗ώκ╡Ύ╝Νbbcchinese.com, email news, newsletter, subscription, full text
The problem is in the first string. Is there any way to print what exactly I am reading? Also is there any way to find the exact encoding of the language of each script?
PS: I would like to mention that the site selected totally randomly as it is representative to the problem I am encountering.
Thank you in advance!
You have problem with the terminal where you are outputting the result. The script works fine and if you output data to file you will get it correctly.
Example:
import urllib2
from bs4 import BeautifulSoup
url = 'http://www.bbc.co.uk/zhongwen/simp/'
page = urllib2.urlopen(url).read().decode("utf-8")
dom = BeautifulSoup(page)
data = dom.findAll('meta', {'name' : 'keywords'})
with open("test.txt", "w") as myfile:
myfile.write(data[0]['content'].encode("utf-8"))
test.txt:
BBC中文网,主页,bbcchinese.com, email news, newsletter, subscription, full text
Which OS and terminal you are using?