Пример #1
0
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
Пример #2
0
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
Пример #3
0
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
Пример #4
0
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