Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Possible optimizations - do not merge #638

Closed
wants to merge 37 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
e0aa49b
Fix typo in dependencies for Ubuntu/Debian
liZe Jan 21, 2018
e1c88e3
Fix text justification for indented text
liZe Jan 21, 2018
be8e969
Fix named pages when broken between two top-level children
liZe Jan 22, 2018
decdc09
Handle content(first-letter)
liZe Jan 22, 2018
7dc9780
Use content(first-letter) as defined for ::first-letter
liZe Jan 22, 2018
cd3e50f
Fix string-set logic
liZe Jan 23, 2018
67b0686
Install extra text packages in doc hacking page
liZe Jan 27, 2018
b24704f
Keep a reference to font_config in Document
liZe Jan 28, 2018
a5bbc22
Use Latin-1-decoded strings instead of bytestrings in pdfrw streams
liZe Jan 28, 2018
1636a37
Fix typo in docstring
liZe Jan 28, 2018
dffab39
Handle @page rule grammar correctly
liZe Jan 28, 2018
f950715
Update needed versions of some libraries
liZe Jan 29, 2018
4624332
Remove useless empty line
liZe Jan 29, 2018
3275ff9
Revert "Use Latin-1-decoded strings instead of bytestrings in pdfrw s…
liZe Jan 30, 2018
2dbfaac
Version 0.42.1
liZe Feb 1, 2018
0621532
I'd do anything to please the linters
liZe Feb 1, 2018
867c67f
Use the current child skip stack when breaking lines with children
liZe Feb 3, 2018
9034aa5
Regression test for #560
liZe Feb 4, 2018
2e5408c
Fix another crash due to the new line breaking algorithm
liZe Feb 4, 2018
6a622d0
Version 0.42.2
liZe Feb 4, 2018
cb67d23
Get only first line's width of inline children to get linebox width
liZe Feb 12, 2018
1b62ca5
Respect text direction for multicolumn layout
liZe Feb 13, 2018
981045d
Split replaced_min_content_width and replaced_max_content_width
liZe Feb 15, 2018
19342fb
Don't translate rtl columns twice
liZe Feb 20, 2018
e206165
Fix replaced_max_content_width
liZe Feb 22, 2018
99ee59a
There's no need to remove the default null log handler
liZe Feb 24, 2018
8f725e2
Fix inline box breaking function
liZe Feb 27, 2018
16ef163
Propagate overflow to the table wrapper
liZe Mar 4, 2018
f631cec
Remove table border from available width when borders collapse
liZe Mar 5, 2018
f8993ca
Ignore overflow_wrap: break-word when calculating min-content width
liZe Mar 5, 2018
a859d8d
Don't optimize resume_at when splitting lines with trailing spaces
liZe Mar 9, 2018
4e1fad3
Fix floating-point number error to fix floating box layout
liZe Mar 22, 2018
c958d3f
Version 0.42.3
liZe Mar 27, 2018
3210ea8
cache Box.margin_height
chancyk Jun 10, 2018
89e269a
short circuit get_clearance
chancyk Jun 10, 2018
71f7415
assign locals to avoid attr lookups
chancyk Jun 10, 2018
bd6a48d
consistent with master
chancyk Jun 10, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 66 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
@@ -1,6 +1,72 @@
WeasyPrint changelog
====================


Versions 0.42.x will only get simple bug fixes backported from the master
branch. New features, opitimizations and complex bug fixes will only be added
to the 43+ versions that don't support Python 2 anymore.

Do not rely on future versions, development on the 0.x branch may be stopped at
any moment.


Version 0.42.3
--------------

Released on 2018-03-27.

Bug fixes:

* `#583 <https://github.com/Kozea/WeasyPrint/issues/583>`_:
Fix floating-point number error to fix floating box layout
* `#586 <https://github.com/Kozea/WeasyPrint/issues/586>`_:
Don't optimize resume_at when splitting lines with trailing spaces
* `#582 <https://github.com/Kozea/WeasyPrint/issues/582>`_:
Fix table layout with no overflow
* `#580 <https://github.com/Kozea/WeasyPrint/issues/580>`_:
Fix inline box breaking function
* `#576 <https://github.com/Kozea/WeasyPrint/issues/576>`_:
Split replaced_min_content_width and replaced_max_content_width
* `#574 <https://github.com/Kozea/WeasyPrint/issues/574>`_:
Respect text direction and don't translate rtl columns twice
* `#569 <https://github.com/Kozea/WeasyPrint/issues/569>`_:
Get only first line's width of inline children to get linebox width


Version 0.42.2
--------------

Released on 2018-02-04.

Bug fixes:

* `#560 <https://github.com/Kozea/WeasyPrint/issues/560>`_:
Fix a couple of crashes and endless loops when breaking lines.


Version 0.42.1
--------------

Released on 2018-02-01.

Bug fixes:

* `#566 <https://github.com/Kozea/WeasyPrint/issues/566>`_:
Don't crash when using @font-config.
* `#567 <https://github.com/Kozea/WeasyPrint/issues/567>`_:
Fix text-indent with text-align: justify.
* `#465 <https://github.com/Kozea/WeasyPrint/issues/465>`_:
Fix string(*, start).
* `#562 <https://github.com/Kozea/WeasyPrint/issues/562>`_:
Handle named pages with pseudo-class.
* `#507 <https://github.com/Kozea/WeasyPrint/issues/507>`_:
Fix running headers.
* `#557 <https://github.com/Kozea/WeasyPrint/issues/557>`_:
Avoid infinite loops in inline_line_width.
* `#555 <https://github.com/Kozea/WeasyPrint/issues/555>`_:
Fix margins, borders and padding in column layouts.


Version 0.42
------------

Expand Down
6 changes: 3 additions & 3 deletions docs/hacking.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ install the `development version`_ of WeasyPrint:
cd WeasyPrint
virtualenv --system-site-packages env
. env/bin/activate
pip install pytest Sphinx -e .
pip install Sphinx -e .[test]
weasyprint --help

This will install WeasyPrint in “editable” mode
(which means that you don’t need to re-install it
every time you make a change in the source code)
as well as `py.test <http://pytest.org/>`_
as well as `pytest <http://pytest.org/>`_
and `Sphinx <http://sphinx.pocoo.org/>`_.

Lastly, in order to pass unit tests, your system must have two particular fonts:
Expand All @@ -43,7 +43,7 @@ The website version is updated automatically when we push to master on GitHub.
Code changes
------------

Use the ``py.test`` command from the ``WeasyPrint`` directory to run the
Use the ``pytest`` command from the ``WeasyPrint`` directory to run the
test suite.

Please report any bugs/feature requests and submit patches/pull requests
Expand Down
16 changes: 9 additions & 7 deletions docs/install.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ Installing
WeasyPrint |version| depends on:

* CPython_ 2.7 or ≥ 3.4
* cairo_ [#]_
* Pango_
* cairo_ ≥ 1.15.0 [#]_
* Pango_ ≥ 1.29.3
* CFFI_ ≥ 0.6
* html5lib_ ≥ 0.999999999
* cairocffi_ ≥ 0.5
Expand All @@ -14,7 +14,7 @@ WeasyPrint |version| depends on:
* CairoSVG_ ≥ 1.0.20
* Pyphen_ ≥ 0.8
* pdfrw_ ≥ 0.4
* Optional: GDK-PixBuf_ [#]_
* Optional: GDK-PixBuf_ ≥ 2.25.0 [#]_

.. _CPython: http://www.python.org/
.. _cairo: http://cairographics.org/
Expand Down Expand Up @@ -69,9 +69,11 @@ If everything goes well, you’re ready to :doc:`start using </tutorial>`
WeasyPrint! Otherwise, please copy the full error message and
`report the problem <http://weasyprint.org/community/>`_.

.. [#] cairo ≥ 1.12 is best but older versions should work too.
The test suite passes on cairo 1.8 and 1.10 with some tests marked as
“expected failures” due to behavior changes or bugs in cairo.
.. [#] cairo ≥ 1.15 is best but older versions may work too. The test suite
passes on cairo 1.12 and 1.14, and passes with some tests marked as
“expected failures” on 1.8 and 1.10 due to behavior changes or bugs in
cairo. With cairo 1.14, WeasyPrint sometimes creates PDF files that may
not be correctly interpreted by GhostScript or CUPS.

.. [#] Without it, PNG and SVG are the only supported image formats.
JPEG, GIF and others are not available.
Expand Down Expand Up @@ -100,7 +102,7 @@ Debian 9.0 Stretch or newer, Ubuntu 16.04 Xenial or newer:

.. code-block:: sh

sudo apt-get install build-essential python3-dev python3-pip python3-cffi libcairo2 libpango-1.0-0 libpangocairo-1.0.0 libgdk-pixbuf2.0-0 libffi-dev shared-mime-info
sudo apt-get install build-essential python3-dev python3-pip python3-cffi libcairo2 libpango-1.0-0 libpangocairo-1.0-0 libgdk-pixbuf2.0-0 libffi-dev shared-mime-info

Debian 8.0 Jessie or newer, Ubuntu 14.04 Trusty or newer (with Python 2, but Python 3 may work):

Expand Down
1 change: 0 additions & 1 deletion docs/tutorial.rst
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,6 @@ by configuring the ``weasyprint`` logger object:

import logging
logger = logging.getLogger('weasyprint')
logger.handlers = [] # Remove the default stderr handler
logger.addHandler(logging.FileHandler('/path/to/weasyprint.log'))

The ``INFO`` level is used to report the rendering progress. It is useful to
Expand Down
2 changes: 1 addition & 1 deletion weasyprint/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
import tinycss2


VERSION = '0.42'
VERSION = '0.42.3'
__version__ = VERSION

# Used for 'User-Agent' in HTTP and 'Creator' in PDF
Expand Down
164 changes: 110 additions & 54 deletions weasyprint/css/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -586,6 +586,82 @@ def computed_from_cascaded(element, cascaded, parent_style, pseudo_type=None,
base_url))


def parse_page_selectors(rule):
"""Parse a page selector rule.

Return a list of page data if the rule is correctly parsed. Page data are a
dict containing:

- 'side' ('left', 'right' or None),
- 'blank' (True or False),
- 'first' (True or False),
- 'name' (page name string or None), and
- 'spacificity' (list of numbers).

Return ``None` if something went wrong while parsing the rule.

"""
# See https://drafts.csswg.org/css-page-3/#syntax-page-selector

tokens = list(remove_whitespace(rule.prelude))
page_data = []

# TODO: Specificity is probably wrong, should clean and test that.
if not tokens:
page_data.append({
'side': None, 'blank': False, 'first': False, 'name': None,
'specificity': [0, 0, 0]})
return page_data

while tokens:
types = {
'side': None, 'blank': False, 'first': False, 'name': None,
'specificity': [0, 0, 0]}

if tokens[0].type == 'ident':
token = tokens.pop(0)
types['name'] = token.value
types['specificity'][0] = 1

if len(tokens) == 1:
return None
elif not tokens:
page_data.append(types)
return page_data

while tokens:
literal = tokens.pop(0)
if literal.type != 'literal':
return None

if literal.value == ':':
if not tokens or tokens[0].type != 'ident':
return None
ident = tokens.pop(0)
pseudo_class = ident.lower_value
if pseudo_class in ('left', 'right'):
if types['side']:
return None
types['side'] = pseudo_class
types['specificity'][2] += 1
elif pseudo_class in ('blank', 'first'):
if types[pseudo_class]:
return None
types[pseudo_class] = True
types['specificity'][1] += 1
else:
return None
elif literal.value == ',':
if tokens and any(types['specificity']):
break
else:
return None

page_data.append(types)

return page_data


def preprocess_stylesheet(device_media_type, base_url, stylesheet_rules,
url_fetcher, matcher, page_rules, fonts,
font_config, ignore_imports=False):
Expand Down Expand Up @@ -671,64 +747,44 @@ def preprocess_stylesheet(device_media_type, base_url, stylesheet_rules,
matcher, page_rules, fonts, font_config, ignore_imports=True)

elif rule.type == 'at-rule' and rule.lower_at_keyword == 'page':
tokens = remove_whitespace(rule.prelude)
types = {
'side': None, 'blank': False, 'first': False, 'name': None}
# TODO: Specificity is probably wrong, should clean and test that.
if not tokens:
specificity = (0, 0, 0)
elif (len(tokens) == 2 and
tokens[0].type == 'literal' and
tokens[0].value == ':' and
tokens[1].type == 'ident'):
pseudo_class = tokens[1].lower_value
if pseudo_class in ('left', 'right'):
types['side'] = pseudo_class
specificity = (0, 0, 1)
elif pseudo_class in ('blank', 'first'):
types[pseudo_class] = True
specificity = (0, 1, 0)
else:
LOGGER.warning('Unknown @page pseudo-class "%s", '
'the whole @page rule was ignored '
'at %s:%s.',
pseudo_class,
rule.source_line, rule.source_column)
continue
elif len(tokens) == 1 and tokens[0].type == 'ident':
types['name'] = tokens[0].value
specificity = (1, 0, 0)
else:
LOGGER.warning('Unsupported @page selector "%s", '
'the whole @page rule was ignored at %s:%s.',
tinycss2.serialize(rule.prelude),
rule.source_line, rule.source_column)
data = parse_page_selectors(rule)

if data is None:
LOGGER.warning(
'Unsupported @page selector "%s", '
'the whole @page rule was ignored at %s:%s.',
tinycss2.serialize(rule.prelude),
rule.source_line, rule.source_column)
continue
ignore_imports = True
page_type = PageType(**types)
# Use a double lambda to have a closure that holds page_types
match = (lambda page_type: lambda page_names: list(
matching_page_types(page_type, names=page_names)))(page_type)
content = tinycss2.parse_declaration_list(rule.content)
declarations = list(preprocess_declarations(base_url, content))

if declarations:
selector_list = [(specificity, None, match)]
page_rules.append((rule, selector_list, declarations))
ignore_imports = True
for page_type in data:
specificity = page_type.pop('specificity')
page_type = PageType(**page_type)
# Use a double lambda to have a closure that holds page_types
match = (lambda page_type: lambda page_names: list(
matching_page_types(page_type, names=page_names)))(
page_type)
content = tinycss2.parse_declaration_list(rule.content)
declarations = list(preprocess_declarations(base_url, content))

for margin_rule in content:
if margin_rule.type != 'at-rule' or (
margin_rule.content is None):
continue
declarations = list(preprocess_declarations(
base_url,
tinycss2.parse_declaration_list(margin_rule.content)))
if declarations:
selector_list = [(
specificity, '@' + margin_rule.lower_at_keyword,
match)]
page_rules.append(
(margin_rule, selector_list, declarations))
selector_list = [(specificity, None, match)]
page_rules.append((rule, selector_list, declarations))

for margin_rule in content:
if margin_rule.type != 'at-rule' or (
margin_rule.content is None):
continue
declarations = list(preprocess_declarations(
base_url,
tinycss2.parse_declaration_list(margin_rule.content)))
if declarations:
selector_list = [(
specificity, '@' + margin_rule.lower_at_keyword,
match)]
page_rules.append(
(margin_rule, selector_list, declarations))

elif rule.type == 'at-rule' and rule.lower_at_keyword == 'font-face':
ignore_imports = True
Expand Down
1 change: 1 addition & 0 deletions weasyprint/css/properties.py
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,7 @@
margin_left
margin_right
opacity
overflow
position
right
top
Expand Down
3 changes: 1 addition & 2 deletions weasyprint/css/validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -1585,8 +1585,7 @@ def validate_content_list_token(token):
elif prototype in (('content', ()), ('content', ('ident',))):
if not args:
return (name, 'text')
elif args[0] in ('text', 'after', 'before'):
# TODO: first-letter should be allowed here too
elif args[0] in ('text', 'after', 'before', 'first-letter'):
return (name, args[0])
elif prototype in (('counter', ('ident',)),
('counters', ('ident', 'string'))):
Expand Down
Loading