Skip to content

Stroke color of annotations cannot be correctly set #4447

New issue

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

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

Already on GitHub? # to your account

Closed
cli-lilly opened this issue Apr 17, 2025 · 13 comments
Closed

Stroke color of annotations cannot be correctly set #4447

cli-lilly opened this issue Apr 17, 2025 · 13 comments
Assignees
Labels
Fixed in next release not a bug not a bug / user error / unable to reproduce

Comments

@cli-lilly
Copy link

cli-lilly commented Apr 17, 2025

dummy.pdf

Description of the bug

When I use annot.set_colors(stroke=(0, 0, 0)) to set annotations' border color to black, the fill color of the annotations are changed to black instead. The border color remains the same as the text color.

How to reproduce the bug

import pymupdf
pdf = pymupdf.open(input_pdf_path)
page = pdf[0]

text_color = (1, 0, 0)
fill_color = (191/255, 1, 1)
border_color = (0, 0, 0)

annot_rect = pymupdf.Rect(90.1, 486.73, 139.26, 499.46)

annot = page.add_freetext_annot(  
    annot_rect,  
    "AETERM",  
    fontname="Arial",  
    fontsize=10,  
    text_color=text_color,
    fill_color=fill_color,   
    border_width=1   
)  

annot.set_colors(stroke=(0, 0, 0))
annot.update()  # Save the annotation to the page
pdf.save(output_pdf_path)

Expected behavior:
The border of the annotation should be black, and the fill color should remains light blue

Actual behavior:
The fill of the annotation is set to black, while the border color is the same as the text color

Image

PyMuPDF version

1.25.4

Operating system

Windows

Python version

3.13

@julian-smith-artifex-com
Copy link
Collaborator

Please add the pdf file input_pdf_path to this issue.

@cli-lilly
Copy link
Author

Due to company policy, I am unable to provide the original PDF file. I have added a dummy pdf file instead, I think you can reproduce the bug on it

@julian-smith-artifex-com
Copy link
Collaborator

Actually don't worry, i think i've reproduced the problem with a blank document.

@JorjMcKie
Copy link
Collaborator

As per the PDF specification, FreeText annotations only support one color in their object definition (/C) which is used for the fill color. Just like e.g. Highlight annotations.
This is the reason for your phenomenon.
So using annot.set_color for FreeText will in most cases not lead to what you want.

@JorjMcKie
Copy link
Collaborator

FreeText annotations often have 3 different colors: fill, border and text color - which is completely beyond what PDF object definition syntax lets you do.
What is more, FreeText annots also support rich text which basically means you can specify text in HTML syntax. Here, separate colors and other text properties can be set for individual text particles.
Use the annotation's .update() method for modifying the colors ... or do it right when creating 😉.

@JorjMcKie
Copy link
Collaborator

I think we need to explain this better in the documentation - i.e. discourage the use of .set_colors for FreeText annots.

@cli-lilly
Copy link
Author

I tried setting the border color to black when creating the annotation in the beginning, but it ended up being the same as the text color:

annot = page.add_freetext_annot(  
    annot_rect,  
    "AETERM",  
    fontname="Arial",  
    fontsize=10,  
    text_color=text_color,
    fill_color=fill_color,   
    border_width=1,
    border_color=border_color  
) 

Other codes remain the same and it gives:

Image

@JorjMcKie
Copy link
Collaborator

Please consult the documentation:

Image

You need to add a rich text annot to achieve your goal.

@JorjMcKie JorjMcKie added the not a bug not a bug / user error / unable to reproduce label Apr 17, 2025
@cli-lilly
Copy link
Author

Thanks, I will try rich text annot instead

@cli-lilly
Copy link
Author

border color can be correctly set with richtext=True. Thank you very much

@julian-smith-artifex-com
Copy link
Collaborator

Reopening this until we've released some improvements in this area - to the documentation, and to raise an exception if a text annotation cannot handle the desired colors.

@cli-lilly
Copy link
Author

I found it can display the correct text color, fill color, and border color with richtext=True. But as soon as I move the annotation, the text in the annotations becomes "<p style="font-size:10pt;fontfamily:Arial; font-family:'Arial'; color:#FF0000"><i><b>AETERM</b></i></p>"
Is there a way to keep displaying this kind of AETERM even after users move the annotation?

Image

julian-smith-artifex-com added a commit that referenced this issue Apr 24, 2025
…olor.

Annot.update() now raises exception of border_color specified if not rich text,
matching Annot.__init__().

Also test exceptions are raised as expected.

Addresses #4447.
julian-smith-artifex-com added a commit that referenced this issue Apr 24, 2025
…olor.

Annot.update() now raises exception of border_color specified if not rich text,
matching Annot.__init__().

Also test exceptions are raised as expected.

Addresses #4447.
@julian-smith-artifex-com
Copy link
Collaborator

Fixed in PyMuPDF-1.26.0.

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
Fixed in next release not a bug not a bug / user error / unable to reproduce
Projects
None yet
Development

No branches or pull requests

3 participants