def text( text: str = "abcd", size: float = 10.0, position: Tuple[int, int] = (0, 0), justify: str = "left", layer: Tuple[int, int] = LAYER.TEXT, ) -> Component: """ adds text .. plot:: :include-source: import pp c = pp.c.text(text="abcd", size=10, position=(0, 0), justify="left", layer=1) pp.plotgds(c) """ scaling = size / 1000 xoffset = position[0] yoffset = position[1] t = pp.Component(name=clean_name(text) + "_{}_{}".format(int(position[0]), int(position[1]))) for i, line in enumerate(text.split("\n")): label = pp.Component(name=t.name + "{}".format(i)) for c in line: ascii_val = ord(c) if c == " ": xoffset += 500 * scaling elif 33 <= ascii_val <= 126: for poly in _glyph[ascii_val]: xpts = np.array(poly)[:, 0] * scaling ypts = np.array(poly)[:, 1] * scaling label.add_polygon([xpts + xoffset, ypts + yoffset], layer=layer) xoffset += (_width[ascii_val] + _indent[ascii_val]) * scaling else: ValueError( "[PHIDL] text(): No glyph for character with ascii value %s" % ascii_val) t.add_ref(label) yoffset -= 1500 * scaling xoffset = position[0] justify = justify.lower() for label in t.references: if justify == "left": pass if justify == "right": label.xmax = position[0] if justify == "center": label.move(origin=label.center, destination=position, axis="x") return t
def manhattan_text(text="abcd", size=10, position=(0, 0), justify="left", layer=LAYER.M1): """ .. plot:: :include-source: import pp c = pp.c.text(text="abcd", size=10, position=(0, 0), justify="left", layer=1) pp.plotgds(c) """ pixel_size = size xoffset = position[0] yoffset = position[1] t = pp.Component(name=clean_name(text) + "_{}_{}".format(int(position[0]), int(position[1]))) for i, line in enumerate(text.split("\n")): l = pp.Component(name=t.name + "{}".format(i)) for c in line: try: if c not in CHARAC_MAP: c = c.upper() pixels = CHARAC_MAP[c] except: print( "character {} could not be written (probably not part of dictionnary)" .format(c)) continue _c = l.add_ref( pixel_array(pixels=pixels, pixel_size=pixel_size, layer=layer)) _c.move((xoffset, yoffset)) l.absorb(_c) xoffset += pixel_size * 6 t.add_ref(l) yoffset -= pixel_size * 6 xoffset = position[0] justify = justify.lower() for l in t.references: if justify == "left": pass if justify == "right": l.xmax = position[0] if justify == "center": l.move(origin=l.center, destination=position, axis="x") return t
def manhattan_text( text: str = "abcd", size: float = 10.0, position: Tuple[float, float] = (0.0, 0.0), justify: str = "left", layer: Tuple[int, int] = LAYER.M1, layers_cladding: List[ListConfig] = None, cladding_offset: float = pp.conf.tech.cladding_offset, ) -> Component: """Pixel based font, guaranteed to be manhattan, without accute angles. .. plot:: :include-source: import pp c = pp.c.manhattan_text(text="abcd", size=10, position=(0, 0), justify="left", layer=1) pp.plotgds(c) """ pixel_size = size xoffset = position[0] yoffset = position[1] t = pp.Component(name=clean_name(text) + "_{}_{}".format(int(position[0]), int(position[1]))) for i, line in enumerate(text.split("\n")): component = pp.Component(name=t.name + "{}".format(i)) for c in line: try: if c not in CHARAC_MAP: c = c.upper() pixels = CHARAC_MAP[c] except BaseException: print( "character {} could not be written (probably not part of dictionnary)" .format(c)) continue _c = component.add_ref( pixel_array(pixels=pixels, pixel_size=pixel_size, layer=layer)) _c.move((xoffset, yoffset)) component.absorb(_c) xoffset += pixel_size * 6 t.add_ref(component) yoffset -= pixel_size * 6 xoffset = position[0] justify = justify.lower() for ref in t.references: if justify == "left": pass if justify == "right": ref.xmax = position[0] if justify == "center": ref.move(origin=ref.center, destination=position, axis="x") points = [ [t.xmin - cladding_offset / 2, t.ymin - cladding_offset], [t.xmax + cladding_offset / 2, t.ymin - cladding_offset], [t.xmax + cladding_offset / 2, t.ymax + cladding_offset], [t.xmin - cladding_offset / 2, t.ymax + cladding_offset], ] if layers_cladding: for layer in layers_cladding: t.add_polygon(points, layer=layer) return t
def write_gds( component, gdspath=None, add_ports_to_all_cells=False, add_port_pins=True, store_hash_geometry=False, with_component_label=False, unit=1e-6, precision=1e-9, remove_previous_markers=False, auto_rename=False ): """ write component to GDS and returs gdspath Args: component (required) gdspath: by default saves it into CONFIG['gds_directory'] add_ports_to_all_cells: to child cells - required to export netlists add_port_pins: show port metadata auto_rename: False by default (otherwise it calls it top_cell) with_component_label unit precission Returns: gdspath """ if gdspath is None: gdspath = CONFIG["gds_directory"] / (component.name + ".gds") gdspath = str(gdspath) if remove_previous_markers: # If the component HAS ports AND markers and we want to # avoid duplicate port markers, then we clear the previous ones port_layer = (LAYER.PORT,) label_layer = (LAYER.TEXT,) component.remove_layers([port_layer]) component.remove_layers([label_layer]) if add_port_pins and add_ports_to_all_cells: referenced_cells = list(component.get_dependencies(recursive=True)) all_cells = [component] + referenced_cells all_cells = list(set(all_cells)) for c in all_cells: add_port_markers(c) elif add_port_pins: add_port_markers(component) folder = os.path.split(gdspath)[0] if folder and not os.path.isdir(folder): os.makedirs(folder) if store_hash_geometry: # Remove any label on hash layer old_label = [l for l in component.labels if l.layer == LAYER.INFO_GEO_HASH] if len(old_label) > 0: for l in old_label: component.labels.remove(l) # Add new hash label # component.label( # text=component.hash_geometry(), # position=component.size_info.cc, # layer=LAYER.INFO_GEO_HASH, # ) # Add new hash label if not hasattr(component, "settings"): component.settings = {} component.settings.update(dict(hash_geometry=component.hash_geometry())) # write component settings into text layer if with_component_label: for i, (k, v) in enumerate(component.settings.items()): component.label( text="{}={}".format(clean_name(k), clean_value(v)), position=component.center + [0, i * 0.4], layer=LAYER.TEXT, ) component.write_gds(gdspath, precision=precision, auto_rename=auto_rename) component.path = gdspath return gdspath