示例#1
0
    def render(self, text, _, color):
        if self.font is None:
            return "", (0, 0)

        fm = QFontMetrics(self.font)
        rect = fm.boundingRect(text)
        im = QImage(
            rect.x() + rect.width(),
            rect.height(),
            QImage.Format_ARGB32_Premultiplied,
        )
        im.fill(QColor(0, 0, 0, 0))
        painter = QPainter()
        painter.begin(im)
        painter.setPen(QPen(QColor(*color)))
        painter.setFont(self.font)
        painter.drawText(QPoint(0 - rect.x(), 0 - rect.y()), text)
        painter.end()

        bits = im.bits()
        try:
            pixels = bits.tobytes()
        except AttributeError:
            bits.setsize(im.byteCount())
            pixels = bytes(bits)
        return pixels, (rect.x() + rect.width(), rect.height())
    def _glowicon_image_imag(self, data, width, height, dark):
        from fsui.qt import QColor, QImage, QPoint, QSize

        transparent_color = data[0]
        num_colors = data[1] + 1
        flags = data[2]
        transparency = flags & 1 != 0
        has_palette = flags & 2 != 0
        compressed = data[3] != 0
        compressed_palette = data[4] != 0
        bitdepth = data[5]
        image_bytes = data[6] * 256 + data[7] + 1
        palette_bytes = data[8] * 256 + data[9] + 1

        print("transparent_color:", transparent_color)
        print("num colors:", num_colors)
        print("flags:", flags)
        print("- transparency:", transparency)
        print("- has_palette:", has_palette)
        print("compression:", compressed)
        print("palette compression:", compressed_palette)
        print("bit depth:", bitdepth)
        print("image bytes:", image_bytes)
        print("palette bytes:", palette_bytes)

        if not transparency:
            transparent_color = -1

        image = QImage(QSize(width, height), QImage.Format_RGBA8888)
        image.fill(0xFFFFFFFF)

        palette = []

        class ParseData:
            bits = []
            bitdepth = 0
            offset = 0
            # line = b""
            palette = True
            compressed = False
            color = []
            done = False
            x = 0
            y = 0
            copy = 0
            produce = 0

        parsedata = ParseData()
        parsedata.offset = 10 + image_bytes
        parsedata.end = 10 + image_bytes + palette_bytes
        parsedata.compressed = compressed_palette
        parsedata.palette = True
        parsedata.bitdepth = 8

        # parsedata.data = data
        # parsedata.ly = 0
        # parsedata.lx = 5
        # parsedata.line = line

        def pushentry(value):
            if parsedata.palette:
                parsedata.color.append(value)
                if len(parsedata.color) == 3:
                    # pylint: disable=unbalanced-tuple-unpacking
                    r, g, b = parsedata.color
                    a = 0xFF
                    print(f"PALETTE{len(palette):02d} 0x{r:02x}{g:02x}{b:02x}")
                    if dark:
                        palette.append(QColor(r * 0.66, g * 0.66, b * 0.66, a))
                    else:
                        palette.append(QColor(r, g, b, a))
                    parsedata.color = []
                # FIXME: More efficient
                # parsedata.bits = parsedata.bits[8:]
                if parsedata.palette and len(palette) >= num_colors:
                    parsedata.palette = False
            elif parsedata.done:
                pass
            else:
                palette_index = value
                # FIXME: Maybe only subtract 1 etc when transparency is True
                # print("palette", palette_index)
                # FIXME: Transparency... correct?
                if palette_index == transparent_color:
                    color = QColor(0x00, 0x00, 0x00, 0x00)
                elif palette_index >= len(palette):
                    color = QColor(0xFF, 0x00, 0x00, 0xFF)
                    print("WARNING, palette_index is", palette_index)
                else:
                    color = palette[palette_index]
                image.setPixelColor(QPoint(parsedata.x, parsedata.y), color)
                # FIXME: More efficient
                # parsedata.bits = parsedata.bits[bitdepth:]
                parsedata.x += 1
                if parsedata.x == width:
                    parsedata.y += 1
                    parsedata.x = 0
                    if parsedata.y == height:
                        parsedata.done = True

        def pushbit(bit):
            parsedata.bits.append(bit)

            if parsedata.produce:
                if len(parsedata.bits) == parsedata.bitdepth:
                    value = bits_to_value(parsedata.bits)
                    for _i in range(parsedata.produce):
                        pushentry(value)
                    parsedata.produce = 0
                    parsedata.bits.clear()

            elif parsedata.copy:
                if len(parsedata.bits) == parsedata.bitdepth:
                    pushentry(bits_to_value(parsedata.bits))
                    parsedata.copy -= 1
                    parsedata.bits.clear()

            elif parsedata.compressed:
                if len(parsedata.bits) == 8:
                    value = bits_to_value(parsedata.bits)
                    if value <= 0x7F:
                        parsedata.copy = value + 1
                    elif value == 0x80:
                        pass
                    else:
                        parsedata.produce = 256 - value + 1
                    parsedata.bits.clear()

            else:
                if len(parsedata.bits) == 8:
                    value = bits_to_value(parsedata.bits[: parsedata.bitdepth])
                    pushentry(value)
                    parsedata.bits.clear()

            # if parsedata.palette:
            #     if len(parsedata.bits) == 8:
            #         parsedata.color.append(bits_to_value(parsedata.bits[0:8]))
            #         if len(parsedata.color) == 3:
            #             # pylint: disable=unbalanced-tuple-unpacking
            #             r, g, b = parsedata.color
            #             a = 0xFF
            #             print(
            #                 f"PALETTE{len(palette):02d} 0x{r:02x}{g:02x}{b:02x}"
            #             )
            #             if dark:
            #                 palette.append(
            #                     QColor(r * 0.66, g * 0.66, b * 0.66, a)
            #                 )
            #             else:
            #                 palette.append(QColor(r, g, b, a))
            #             parsedata.color = []
            #         # FIXME: More efficient
            #         parsedata.bits = parsedata.bits[8:]

            #         if parsedata.palette and len(palette) >= num_colors:
            #             parsedata.palette = False
            # elif parsedata.done:
            #     pass
            # else:
            #     # print("x")
            #     if len(parsedata.bits) == bitdepth:
            #         palette_index = bits_to_value(parsedata.bits[0:bitdepth])
            #         # FIXME: Maybe only subtract 1 etc when transparency is True
            #         # print("palette", palette_index)
            #         # FIXME: Transparency... correct?
            #         if palette_index == 0 and transparency:
            #             color = QColor(0x00, 0x00, 0x00, 0x00)
            #         elif palette_index >= len(palette):
            #             color = QColor(0xFF, 0x00, 0x00, 0xFF)
            #             print("WARNING, palette_index is", palette_index)
            #         else:
            #             color = palette[palette_index]
            #         image.setPixelColor(
            #             QPoint(parsedata.x, parsedata.y), color
            #         )
            #         # FIXME: More efficient
            #         parsedata.bits = parsedata.bits[bitdepth:]
            #         parsedata.x += 1
            #         if parsedata.x == width:
            #             parsedata.y += 1
            #             parsedata.x = 0
            #             if parsedata.y == height:
            #                 parsedata.done = True

        def pushbyte(value):
            for i in range(8):
                pushbit(value >> (7 - i) & 1)

        # def flush():
        #     print("flushing", len(parsedata.bits), "bits")
        #     parsedata.bits = []

        def dobyte():
            value = data[parsedata.offset]
            # if parsedata.compressed:
            #     # 0x00 .. 0x7F copy the next n entries as they are, where n is "RLE-value"+1
            #     # 0x80         ignore this, do nothing
            #     # 0x81 .. 0xFF produce the next entry n times, where n is 256-"RLE-value"+1
            #     #             (if using signed chars n is "RLE-value"+1)
            #     if parsedata.produce:
            #         for _i in range(parsedata.produce):
            #             pushbyte(value)
            #         parsedata.produce = 0
            #     elif parsedata.copy:
            #         pushbyte(value)
            #         parsedata.copy -= 1
            #     elif value <= 0x7F:
            #         parsedata.copy = value + 1
            #     elif value == 0x80:
            #         pass
            #     else:
            #         parsedata.produce = 256 - value + 1
            # else:
            #     if not parsedata.palette and not parsedata.compressed:
            #         # FIXME: Only push bitdepth bits
            #         raise Exception("TODO: Unsupported")
            #     else:
            #         pushbyte(value)

            pushbyte(value)
            parsedata.offset += 1

        while parsedata.offset < parsedata.end:
            dobyte()
        print(len(parsedata.bits))

        parsedata.offset = 10
        parsedata.end = 10 + image_bytes
        parsedata.compressed = compressed
        parsedata.palette = False
        parsedata.copy = 0
        parsedata.produce = 0
        parsedata.bitdepth = bitdepth

        print(parsedata.offset, parsedata.end)
        while parsedata.offset < parsedata.end:
            dobyte()

        print(width, height)
        print(parsedata.x, parsedata.y)

        # import sys
        # sys.exit(1)
        return ShellIconImage(image)
    def create_retroarch_layout(self):
        if self.stretching() == self.STRETCH_FILL_SCREEN or not self.bezel():
            return
        if not self.use_fullscreen():
            return

        # FIXME: file cmp?
        paths = self.prepare_emulator_skin()
        print(paths)

        # FIXME: SUPPORT frame = 0 ( bezel = 0) option

        # FIXME: With no bezel, we should still use a black bezel to
        # hide screen stretching

        screen_width, screen_height = self.screen_size()
        # dst_x = 0
        dst_y = 0
        # dst_w = 0
        # dst_w = 160
        dst_h = screen_height

        # Bezel size is normalized against 1080 (height)
        scale = screen_height / 1080
        # Bezel width: 160
        dst_w = round(160 * scale)

        game_x, game_y, game_w, game_h = self.display_rect_fullscreen()

        from fsui.qt import Qt, QImage, QPainter, QRect, QSize

        image = QImage(QSize(screen_width, screen_height),
                       QImage.Format_RGBA8888)
        image.fill(Qt.transparent)
        # painter = image.paintEngine()
        painter = QPainter(image)

        dst_x = game_x - dst_w
        left = QImage(paths["left"])
        painter.drawImage(QRect(dst_x, dst_y, dst_w, dst_h), left)

        dst_x = game_x + game_w
        right = QImage(paths["right"])
        painter.drawImage(QRect(dst_x, dst_y, dst_w, dst_h), right)
        painter.end()

        overlay_png_file = self.temp_file("overlay.png").path
        image.save(overlay_png_file)

        # noinspection SpellCheckingInspection
        overlay_config = """overlays = 1
overlay0_overlay = {overlay}
overlay0_full_screen = true
overlay0_rect = "0.0,0.0,1.0,1.0"
overlay0_descs = 0
""".format(overlay=overlay_png_file)
        #         overlay_config = (
        #             """overlays = 2
        # overlay0_overlay = {left}
        # overlay0_full_screen = true
        # overlay0_rect = "0.0,0.0,0.12,1.0"
        # overlay0_descs = 0
        # overlay1_overlay = {right}
        # overlay1_full_screen = true
        # overlay1_rect = "0.8,0.0,0.2,1.0"
        # overlay1_descs = 0
        #
        # """.format(left=paths["left"], right=paths["right"]))
        overlay_config_file = self.temp_file("overlay.cfg")
        with open(overlay_config_file.path, "w") as f:
            f.write(overlay_config)
        return overlay_config_file.path
示例#4
0
    def create_retroarch_layout(self):
        if self.stretching() == self.STRETCH_FILL_SCREEN or not self.bezel():
            return
        if not self.use_fullscreen():
            return

        # FIXME: file cmp?
        paths = self.prepare_emulator_skin()
        print(paths)

        # FIXME: SUPPORT frame = 0 ( bezel = 0) option

        # FIXME: With no bezel, we should still use a black bezel to
        # hide screen stretching

        screen_width, screen_height = self.screen_size()
        # dst_x = 0
        dst_y = 0
        # dst_w = 0
        # dst_w = 160
        dst_h = screen_height

        # Bezel size is normalized against 1080 (height)
        scale = screen_height / 1080
        # Bezel width: 160
        dst_w = round(160 * scale)

        game_x, game_y, game_w, game_h = self.display_rect_fullscreen()

        from fsui.qt import Qt, QImage, QPainter, QRect, QSize

        image = QImage(
            QSize(screen_width, screen_height), QImage.Format_RGBA8888
        )
        image.fill(Qt.transparent)
        # painter = image.paintEngine()
        painter = QPainter(image)

        dst_x = game_x - dst_w
        left = QImage(paths["left"])
        painter.drawImage(QRect(dst_x, dst_y, dst_w, dst_h), left)

        dst_x = game_x + game_w
        right = QImage(paths["right"])
        painter.drawImage(QRect(dst_x, dst_y, dst_w, dst_h), right)
        painter.end()

        overlay_png_file = self.temp_file("overlay.png").path
        image.save(overlay_png_file)

        # noinspection SpellCheckingInspection
        overlay_config = """overlays = 1
overlay0_overlay = {overlay}
overlay0_full_screen = true
overlay0_rect = "0.0,0.0,1.0,1.0"
overlay0_descs = 0
""".format(
            overlay=overlay_png_file
        )
        #         overlay_config = (
        #             """overlays = 2
        # overlay0_overlay = {left}
        # overlay0_full_screen = true
        # overlay0_rect = "0.0,0.0,0.12,1.0"
        # overlay0_descs = 0
        # overlay1_overlay = {right}
        # overlay1_full_screen = true
        # overlay1_rect = "0.8,0.0,0.2,1.0"
        # overlay1_descs = 0
        #
        # """.format(left=paths["left"], right=paths["right"]))
        overlay_config_file = self.temp_file("overlay.cfg")
        with open(overlay_config_file.path, "w") as f:
            f.write(overlay_config)
        return overlay_config_file.path