diff --git a/Expolration_set_pattern.py b/Expolration_set_pattern.py new file mode 100644 index 000000000..d6b51c5dc --- /dev/null +++ b/Expolration_set_pattern.py @@ -0,0 +1,43 @@ +from fpdf import FPDF + +# Create instance of FPDF class +pdf = FPDF() + +# Add a page +pdf.add_page() + +# Set fill color (RGB) +pdf.set_fill_color(255, 205, 0) # Setting the color to red + +# pdf.set_page_background('/Users/lamamasri/Desktop/image_13.gif') +w1 = 10 +w2 = 10 +w3 = 50 +w4 = 40 +pdf.rect(10, 10, 50, 30) + +n = 0 +while n <= 50: + pdf.rect(w1, w2, w3 / 10, w3 / 10, "F") + pdf.rect(w1, w2 + 10, w3 / 10, w3 / 10, "F") + pdf.rect(w1, w2 + 20, w3 / 10, w3 / 10, "F") + pdf.rect(w1, w2 + 28, w3 / 10, w3 / 10, "F") + w1 = w1 + w3 / 5 + + n = n + 10 + print("N1: ", n) + print("W1; ,", w1) + +# Draw a filled rectangle +# for i in range (w3): +# pdf.rect(w1, w2,w3/10, w3/10, 'F') + +# pdf.rect(10, 10, 5, 5, 'F') # 'F' argument is for fill + +# pdf.rect(20, 10, 5, 5, 'F') + +# pdf.rect(30, 10, 5, 5, 'F') + + +# Output the PDF +pdf.output("filled_rectangle.pdf") diff --git a/Working_function_rect_circ.py b/Working_function_rect_circ.py new file mode 100644 index 000000000..59d1846d3 --- /dev/null +++ b/Working_function_rect_circ.py @@ -0,0 +1,37 @@ +from fpdf import FPDF + +pdf = FPDF() + +# Add a page +pdf.add_page() + +# Set fill color (RGB) +pdf.set_fill_color(255, 205, 0) # Setting the color to yellow + +# Draw the outer rectangle +outer_rect_x, outer_rect_y, outer_rect_w, outer_rect_h = 10, 10, 50, 30 +pdf.ellipse( + outer_rect_x, outer_rect_y, outer_rect_w, outer_rect_h, "F" +) # Fill the outer rectangle + +# Pattern properties +pattern_width, pattern_height = 5, 10 # Width and height of the small rectangles +cols = int(outer_rect_w / pattern_width) # Number of small rectangles horizontally +rows = int(outer_rect_h / pattern_height) # Number of small rectangles vertically + +# Set color for the pattern +pdf.set_fill_color(255, 255, 255) # White for the spacing + +# Create the pattern +for i in range(cols): + for j in range(rows): + if (i + j) % 2 == 0: # Check for alternate placement + x = outer_rect_x + i * pattern_width + y = outer_rect_y + j * pattern_height + pdf.rect(x, y, pattern_width, pattern_height, "F") + +pdf.set_draw_color(0, 0, 0) # Black border +pdf.ellipse(outer_rect_x, outer_rect_y, outer_rect_w, outer_rect_h) + +# Output the PDF +pdf.output("pattern_filled_rectangle.pdf") diff --git a/filled_rectangle.pdf b/filled_rectangle.pdf new file mode 100644 index 000000000..f83d9a4b8 Binary files /dev/null and b/filled_rectangle.pdf differ diff --git a/fpdf/drawing.py b/fpdf/drawing.py index adcb3ff51..84453f691 100644 --- a/fpdf/drawing.py +++ b/fpdf/drawing.py @@ -1085,6 +1085,7 @@ class GraphicsStyle: "intersection_rule", "fill_color", "fill_opacity", + "fill_pattern", "stroke_color", "stroke_opacity", "blend_mode", @@ -1149,6 +1150,7 @@ def __init__(self): self.intersection_rule = self.INHERIT self.fill_color = self.INHERIT self.fill_opacity = self.INHERIT + self.fill_pattern = self.INHERIT self.stroke_color = self.INHERIT self.stroke_opacity = self.INHERIT self.blend_mode = self.INHERIT @@ -4206,3 +4208,28 @@ def render_debug( pfx, _push_stack=_push_stack, ) + + +class TilingPattern: + def __init__( + self, + pattern_type=1, + paint_type=1, + tiling_type=1, + bbox=None, + x_step=20, + y_step=20, + resources=None, + matrix=None, + ): + self.pattern_type = pattern_type + self.paint_type = paint_type + self.tiling_type = tiling_type + self.bbox = bbox if bbox is not None else [0, 0, 10, 10] + self.x_step = x_step + self.y_step = y_step + self.resources = resources if resources is not None else {} + self.matrix = matrix if matrix is not None else [1, 0, 0, 1, 0, 0] + @staticmethod # remove once the serialize is fully implememented + def serialize(): + return "/Pattern cs /P1 scn" # place holder to be fixed diff --git a/fpdf/enums.py b/fpdf/enums.py index f998a796c..0b25fa64d 100644 --- a/fpdf/enums.py +++ b/fpdf/enums.py @@ -326,44 +326,43 @@ def should_fill_cell(self, i, j): raise NotImplementedError -class RenderStyle(CoerciveEnum): - "Defines how to render shapes" - - D = intern("DRAW") - """ - Draw lines. - Line color can be controlled with `fpdf.fpdf.FPDF.set_draw_color()`. - Line thickness can be controlled with `fpdf.fpdf.FPDF.set_line_width()`. - """ - - F = intern("FILL") - """ - Fill areas. - Filling color can be controlled with `fpdf.fpdf.FPDF.set_fill_color()`. - """ - - DF = intern("DRAW_FILL") - "Draw lines and fill areas" - - @property - def operator(self): - return {self.D: "S", self.F: "f", self.DF: "B"}[self] - - @property - def is_draw(self): - return self in (self.D, self.DF) - - @property - def is_fill(self): - return self in (self.F, self.DF) - @classmethod - def coerce(cls, value): - if not value: - return cls.D - if value == "FD": - value = "DF" - return super(cls, cls).coerce(value) +class RenderStyle(CoerciveEnum): + "Defines how to render shapes" +D = intern("DRAW") +""" +Draw lines. +Line color can be controlled with `fpdf.fpdf.FPDF.set_draw_color()`. +Line thickness can be controlled with `fpdf.fpdf.FPDF.set_line_width()`. +""" +F = intern("FILL") +""" +Fill areas. +Filling color can be controlled with `fpdf.fpdf.FPDF.set_fill_color()`. +""" +DF = intern("DRAW_FILL") +"Draw lines and fill areas" +# adding pattern +P = intern("PATTERN") +@property +def operator(self): + return {self.D: "S", self.F: "f", self.DF: "B", self.P: "f"}[self] + +@property + def is_draw(self): + return self in (self.D, self.DF, self.P) # Include pattern in drawing + @property + def is_fill(self): + return self in (self.F, self.DF, self.P) + @classmethod + def coerce(cls, value): + if not value: + return cls.D + if value == "FD": + value = "DF" +return super(cls, cls).coerce(value) + + class TextMode(CoerciveIntEnum): diff --git a/fpdf/fpdf.py b/fpdf/fpdf.py index 391a67ab9..8bc70b89e 100644 --- a/fpdf/fpdf.py +++ b/fpdf/fpdf.py @@ -106,6 +106,7 @@ class Image: PDFPage, ZOOM_CONFIGS, stream_content_for_raster_image, + PDFPattern ) from .recorder import FPDFRecorder from .sign import Signature @@ -263,6 +264,7 @@ def __init__( self.page = 0 # current page number self.pages = {} # array of PDFPage objects starting at index 1 self.fonts = {} # map font string keys to an instance of CoreFont or TTFFont + self.patterns = {} # map pattern fill objects self.links = {} # array of Destination objects starting at index 1 self.embedded_files = [] # array of PDFEmbeddedFile self.image_cache = ImageCache() @@ -311,6 +313,7 @@ def __init__( ) self.draw_color = self.DEFAULT_DRAW_COLOR self.fill_color = self.DEFAULT_FILL_COLOR + self.fill_pattern = self.DEFAULT_FILL_PATTERN self.text_color = self.DEFAULT_TEXT_COLOR self.page_background = None self.dash_pattern = dict(dash=0, gap=0, phase=0) @@ -1019,6 +1022,48 @@ def set_fill_color(self, r, g=-1, b=-1): if self.page > 0: self._out(self.fill_color.serialize().lower()) + def set_fill_pattern(self, bbox, x_step, y_step, pattern_type, paint_type=None, tiling_type=1, resources=None, matrix=None): + """ + Defines the pattern used for all filling operations (filled rectangles and cell backgrounds). + It can be expressed in RGB components or grey scale. + The method can be called before the first page is created and the value is retained from page to page. + + Args: + r (int, tuple, fpdf.drawing.DeviceGray, fpdf.drawing.DeviceRGB): if `g` and `b` are given, this indicates the red component. + Else, this indicates the grey level. The value must be between 0 and 255. + g (int): green component (between 0 and 255) + b (int): blue component (between 0 and 255) + """ + #print("Hello") + pattern = PDFPattern( + pattern_type= pattern_type, # Assuming tiling pattern is always used + paint_type=paint_type, + tiling_type=tiling_type, + bbox=bbox, + x_step=x_step, + y_step=y_step, + resources=resources, + matrix=matrix + ) + + # Add the pattern to a patterns dictionary in the PDF document + pattern_id = len(self.patterns) + 1 + self.patterns[pattern_id] = pattern + #print(self.patterns) + # Set this pattern as the current fill pattern + self.current_fill_pattern = pattern_id + #print(self.current_fill_pattern) + + def set_current_pattern(self, pattern_id): + + if pattern_id in self.patterns: + + self.current_fill_pattern = pattern_id + + else: + + raise ValueError(f"Pattern ID '{pattern_id}' not found in patterns.") + def set_text_color(self, r, g=-1, b=-1): """ Defines the color used for text. @@ -1339,6 +1384,39 @@ def dashed_line(self, x1, y1, x2, y2, dash_length=1, space_length=1): self.line(x1, y1, x2, y2) self.set_dash_pattern() + def apply_fill_pattern(self, pattern_id, x, y, w, h): + pattern = self.patterns.get(pattern_id) + if pattern: + + # Use the pattern's bbox to determine the size of each tile + pattern_width, pattern_height = pattern.bbox[2], pattern.bbox[3] + + # Use the pattern's x_step and y_step for spacing + x_step, y_step = pattern.x_step, pattern.y_step + + # Calculate how many times the pattern will repeat + x_repeat = int(w / x_step) + y_repeat = int(h / y_step) + + # Loop through and draw the pattern + for i in range(x_repeat): + for j in range(y_repeat): + # Calculate the top-left corner of the current pattern tile + pattern_x = x + i * x_step + pattern_y = y + j * y_step + if pattern.pattern_type == "circles": + if pattern.paint_type is not None: + self.set_fill_color(*pattern.paint_type) + self.ellipse(pattern_x, pattern_y, pattern_width, pattern_height, 'F') + self.ellipse(pattern_x, pattern_y, pattern_width, pattern_height, 'D') + elif pattern.pattern_type == "squares": + if pattern.paint_type is not None: + self.set_fill_color(*pattern.paint_type) + self.rect(pattern_x, pattern_y, pattern_width, pattern_height, 'F') + self.rect(pattern_x, pattern_y, pattern_width, pattern_height, 'D') + else: + raise ValueError('Not defined pattern type') + @check_page def rect(self, x, y, w, h, style=None, round_corners=False, corner_radius=0): """ @@ -1368,8 +1446,19 @@ def rect(self, x, y, w, h, style=None, round_corners=False, corner_radius=0): corner_radius: Optional radius of the corners """ - + style = RenderStyle.coerce(style) + + + if style == RenderStyle.P: + + # Check if a current pattern is set and apply it + if self.current_fill_pattern is not None: + + self.apply_fill_pattern(self.current_fill_pattern, x, y, w, h) + + return None + if round_corners is not False: self._draw_rounded_rect(x, y, w, h, style, round_corners, corner_radius) else: @@ -2581,6 +2670,7 @@ def local_context( line_width=None, draw_color=None, fill_color=None, + fill_pattern=None, text_color=None, dash_pattern=None, **kwargs, @@ -2664,6 +2754,8 @@ def local_context( self.set_draw_color(draw_color) if fill_color is not None: self.set_fill_color(fill_color) + if fill_pattern is not None: + self.set_fill_pattern() if text_color is not None: self.set_text_color(text_color) if dash_pattern is not None: diff --git a/fpdf/graphics_state.py b/fpdf/graphics_state.py index 450e259cc..b16db7b68 100644 --- a/fpdf/graphics_state.py +++ b/fpdf/graphics_state.py @@ -6,7 +6,7 @@ in non-backward-compatible ways. """ -from .drawing import DeviceGray +from .drawing import DeviceGray, TilingPattern from .enums import CharVPos, TextEmphasis, TextMode from .fonts import FontFace @@ -26,6 +26,7 @@ class GraphicsStateMixin: DEFAULT_DRAW_COLOR = DeviceGray(0) DEFAULT_FILL_COLOR = DeviceGray(0) DEFAULT_TEXT_COLOR = DeviceGray(0) + DEFAULT_FILL_PATTERN = TilingPattern() def __init__(self, *args, **kwargs): self.__statestack = [ diff --git a/fpdf/output.py b/fpdf/output.py index 9cd2c1274..04a14ec9c 100644 --- a/fpdf/output.py +++ b/fpdf/output.py @@ -78,6 +78,30 @@ def __init__(self, subtype, base_font, encoding=None, d_w=None, w=None): self.c_i_d_to_g_i_d_map = None +class PDFPattern(PDFObject): + def __init__( + self, + pattern_type, + paint_type, + tiling_type, + bbox, + x_step, + y_step, + resources=None, + matrix=None, + ): + super().__init__() + self.type = Name("Pattern") + self.pattern_type = pattern_type + self.paint_type = paint_type + self.tiling_type = tiling_type + self.bbox = bbox + self.x_step = x_step + self.y_step = y_step + self.resources = resources if resources else None + self.matrix = matrix if matrix else None + + class CIDSystemInfo(PDFObject): def __init__(self): super().__init__() @@ -377,6 +401,7 @@ def bufferize(self): for embedded_file in fpdf.embedded_files: self._add_pdf_obj(embedded_file, "embedded_files") font_objs_per_index = self._add_fonts() + # pattern_objs_per_index = self._add_patterns() img_objs_per_index = self._add_images() gfxstate_objs_per_name = self._add_gfxstates() resources_dict_obj = self._add_resources_dict( @@ -691,6 +716,24 @@ def format_code(unicode): return font_objs_per_index + def _add_patterns(self): + print("adding patterns") + pattern_objs_per_index = {} + for pattern in sorted(self.patterns.values(), key=lambda pattern: pattern.i): + # Assuming each pattern has an index and necessary properties + # Define a tiling pattern + tiling_pattern_obj = PDFPattern( + pattern_type=1, # Tiling pattern + paint_type=1, # Colored tiling pattern + tiling_type=1, # Constant spacing + bbox=[0, 0, 8, 8], # The pattern cell's bounding box + x_step=12, # Horizontal spacing + y_step=12 # Vertical spacing + # Resources and matrix could be added if necessary + ) + self._add_pdf_obj(tiling_pattern_obj, "patterns") + pattern_objs_per_index[pattern.i] = tiling_pattern_obj + def _add_images(self): img_objs_per_index = {} for img in sorted( diff --git a/pattern_filled_rectangle.pdf b/pattern_filled_rectangle.pdf new file mode 100644 index 000000000..9f8badba3 Binary files /dev/null and b/pattern_filled_rectangle.pdf differ diff --git a/trial.ipynb b/trial.ipynb new file mode 100644 index 000000000..246281888 --- /dev/null +++ b/trial.ipynb @@ -0,0 +1,149 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 11, + "id": "2ea6ad7a", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{1: }\n", + "DeviceRGB(r=0.09019607843137255, g=0.25882352941176473, b=0.796078431372549, a=None)\n", + "0.0902 0.2588 0.7961 rg\n", + "DeviceRGB(r=0.09019607843137255, g=0.25882352941176473, b=0.796078431372549, a=None)\n", + "0.0902 0.2588 0.7961 rg\n", + "DeviceRGB(r=0.09019607843137255, g=0.25882352941176473, b=0.796078431372549, a=None)\n", + "0.0902 0.2588 0.7961 rg\n", + "DeviceRGB(r=0.09019607843137255, g=0.25882352941176473, b=0.796078431372549, a=None)\n", + "0.0902 0.2588 0.7961 rg\n", + "DeviceRGB(r=0.09019607843137255, g=0.25882352941176473, b=0.796078431372549, a=None)\n", + "0.0902 0.2588 0.7961 rg\n", + "DeviceRGB(r=0.09019607843137255, g=0.25882352941176473, b=0.796078431372549, a=None)\n", + "0.0902 0.2588 0.7961 rg\n", + "DeviceRGB(r=0.09019607843137255, g=0.25882352941176473, b=0.796078431372549, a=None)\n", + "0.0902 0.2588 0.7961 rg\n", + "DeviceRGB(r=0.09019607843137255, g=0.25882352941176473, b=0.796078431372549, a=None)\n", + "0.0902 0.2588 0.7961 rg\n", + "DeviceRGB(r=0.09019607843137255, g=0.25882352941176473, b=0.796078431372549, a=None)\n", + "0.0902 0.2588 0.7961 rg\n", + "DeviceRGB(r=0.09019607843137255, g=0.25882352941176473, b=0.796078431372549, a=None)\n", + "0.0902 0.2588 0.7961 rg\n", + "DeviceRGB(r=0.09019607843137255, g=0.25882352941176473, b=0.796078431372549, a=None)\n", + "0.0902 0.2588 0.7961 rg\n", + "DeviceRGB(r=0.09019607843137255, g=0.25882352941176473, b=0.796078431372549, a=None)\n", + "0.0902 0.2588 0.7961 rg\n", + "DeviceRGB(r=0.09019607843137255, g=0.25882352941176473, b=0.796078431372549, a=None)\n", + "0.0902 0.2588 0.7961 rg\n", + "DeviceRGB(r=0.09019607843137255, g=0.25882352941176473, b=0.796078431372549, a=None)\n", + "0.0902 0.2588 0.7961 rg\n", + "DeviceRGB(r=0.09019607843137255, g=0.25882352941176473, b=0.796078431372549, a=None)\n", + "0.0902 0.2588 0.7961 rg\n", + "DeviceRGB(r=0.09019607843137255, g=0.25882352941176473, b=0.796078431372549, a=None)\n", + "0.0902 0.2588 0.7961 rg\n", + "DeviceRGB(r=0.09019607843137255, g=0.25882352941176473, b=0.796078431372549, a=None)\n", + "0.0902 0.2588 0.7961 rg\n", + "DeviceRGB(r=0.09019607843137255, g=0.25882352941176473, b=0.796078431372549, a=None)\n", + "0.0902 0.2588 0.7961 rg\n", + "DeviceRGB(r=0.09019607843137255, g=0.25882352941176473, b=0.796078431372549, a=None)\n", + "0.0902 0.2588 0.7961 rg\n", + "DeviceRGB(r=0.09019607843137255, g=0.25882352941176473, b=0.796078431372549, a=None)\n", + "0.0902 0.2588 0.7961 rg\n", + "DeviceRGB(r=0.09019607843137255, g=0.25882352941176473, b=0.796078431372549, a=None)\n", + "0.0902 0.2588 0.7961 rg\n", + "DeviceRGB(r=0.09019607843137255, g=0.25882352941176473, b=0.796078431372549, a=None)\n", + "0.0902 0.2588 0.7961 rg\n", + "DeviceRGB(r=0.09019607843137255, g=0.25882352941176473, b=0.796078431372549, a=None)\n", + "0.0902 0.2588 0.7961 rg\n", + "DeviceRGB(r=0.09019607843137255, g=0.25882352941176473, b=0.796078431372549, a=None)\n", + "0.0902 0.2588 0.7961 rg\n", + "DeviceRGB(r=0.09019607843137255, g=0.25882352941176473, b=0.796078431372549, a=None)\n", + "0.0902 0.2588 0.7961 rg\n", + "{1: , 2: }\n", + "{1: , 2: , 3: }\n" + ] + }, + { + "ename": "ValueError", + "evalue": "Not defined pattern type", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[11], line 16\u001b[0m\n\u001b[1;32m 13\u001b[0m pdf\u001b[38;5;241m.\u001b[39mrect(\u001b[38;5;241m100\u001b[39m,\u001b[38;5;241m100\u001b[39m,\u001b[38;5;241m50\u001b[39m,\u001b[38;5;241m50\u001b[39m,\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mPATTERN\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 15\u001b[0m pdf\u001b[38;5;241m.\u001b[39mset_fill_pattern([\u001b[38;5;241m0\u001b[39m,\u001b[38;5;241m0\u001b[39m,\u001b[38;5;241m5\u001b[39m,\u001b[38;5;241m5\u001b[39m],\u001b[38;5;241m10\u001b[39m, \u001b[38;5;241m10\u001b[39m, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124ms\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m---> 16\u001b[0m pdf\u001b[38;5;241m.\u001b[39mrect(\u001b[38;5;241m50\u001b[39m,\u001b[38;5;241m50\u001b[39m,\u001b[38;5;241m50\u001b[39m,\u001b[38;5;241m50\u001b[39m,\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mPATTERN\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 18\u001b[0m pdf\u001b[38;5;241m.\u001b[39moutput(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mtrying.pdf\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n", + "File \u001b[0;32m~/Desktop/p5/fpdf2-b/fpdf/fpdf.py:202\u001b[0m, in \u001b[0;36mcheck_page..wrapper\u001b[0;34m(self, *args, **kwargs)\u001b[0m\n\u001b[1;32m 200\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mpage \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m (kwargs\u001b[38;5;241m.\u001b[39mget(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mdry_run\u001b[39m\u001b[38;5;124m\"\u001b[39m) \u001b[38;5;129;01mor\u001b[39;00m kwargs\u001b[38;5;241m.\u001b[39mget(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124msplit_only\u001b[39m\u001b[38;5;124m\"\u001b[39m)):\n\u001b[1;32m 201\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m FPDFException(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mNo page open, you need to call add_page() first\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m--> 202\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m fn(\u001b[38;5;28mself\u001b[39m, \u001b[38;5;241m*\u001b[39margs, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n", + "File \u001b[0;32m~/Desktop/p5/fpdf2-b/fpdf/fpdf.py:1450\u001b[0m, in \u001b[0;36mFPDF.rect\u001b[0;34m(self, x, y, w, h, style, round_corners, corner_radius)\u001b[0m\n\u001b[1;32m 1447\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m style \u001b[38;5;241m==\u001b[39m RenderStyle\u001b[38;5;241m.\u001b[39mP:\n\u001b[1;32m 1448\u001b[0m \u001b[38;5;66;03m# Check if a current pattern is set and apply it\u001b[39;00m\n\u001b[1;32m 1449\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mcurrent_fill_pattern \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[0;32m-> 1450\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mapply_fill_pattern(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mcurrent_fill_pattern, x, y, w, h)\n\u001b[1;32m 1451\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m \n\u001b[1;32m 1453\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m round_corners \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mFalse\u001b[39;00m:\n", + "File \u001b[0;32m~/Desktop/p5/fpdf2-b/fpdf/fpdf.py:1412\u001b[0m, in \u001b[0;36mFPDF.apply_fill_pattern\u001b[0;34m(self, pattern_id, x, y, w, h)\u001b[0m\n\u001b[1;32m 1410\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mrect(pattern_x, pattern_y, pattern_width, pattern_height, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mD\u001b[39m\u001b[38;5;124m'\u001b[39m)\n\u001b[1;32m 1411\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m-> 1412\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mNot defined pattern type\u001b[39m\u001b[38;5;124m'\u001b[39m)\n", + "\u001b[0;31mValueError\u001b[0m: Not defined pattern type" + ] + } + ], + "source": [ + "from fpdf import FPDF\n", + "pdf = FPDF()\n", + "pdf.compress= False\n", + "pdf.add_page()\n", + "\n", + "#color is optional \n", + "pdf.set_fill_pattern([0,0,5,5],10, 10,\"circles\", (23,66,203))\n", + "pdf.rect(10,10,50,50,\"PATTERN\")\n", + "\n", + "pdf.set_fill_pattern([0,0,5,5],10, 10,\"squares\")\n", + "pdf.rect(100,100,50,50,\"PATTERN\")\n", + "\n", + "#should get error if not circle or square\n", + "#pdf.set_fill_pattern([0,0,5,5],10, 10, \"s\")\n", + "#pdf.rect(50,50,50,50,\"PATTERN\")\n", + "\n", + "pdf.output(\"trying.pdf\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cd625700", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c0e1098a", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "707dd1fe", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.4" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/trying.pdf b/trying.pdf new file mode 100644 index 000000000..1c9083c18 Binary files /dev/null and b/trying.pdf differ