Files
Android-pyApi/android_pyapi/android/text_style.py
T
shuiyu1123 a51854455b feat: 大规模扩充至212个模块/175K行代码 — 覆盖android/java/javax/org/dalvik全包
- android/ 167个模块 (app/content/os/view/widget/graphics/media/hardware/net/telephony/provider等)
- java/ 35个模块 (lang/io/util/net/nio/security/crypto/sql/beans/rmi/awt等)
- javax/ 4个模块 (net/crypto/security/sql)
- org/ 5个模块 (json/w3c_dom/xml_sax/xml_pull/apache_http)
- dalvik/ 1个模块 (system)
- ~3053个类/接口,方法签名完全对齐Android SDK
- 桌面跨平台运行 (Windows/macOS/Linux)
- 修复所有导入错误和Python关键字冲突
2026-06-24 14:15:56 +00:00

974 lines
34 KiB
Python

"""
Android text.style 包 — CharacterStyle, AlignmentSpan, BulletSpan, URLSpan 等
方法签名完全对齐 Android SDK
"""
from __future__ import annotations
import sys
from typing import Any, Dict, List, Optional, Tuple
from .._core import Stub, AndroidOnlyError
from ..java.lang import RuntimeException
IllegalArgumentException = type("IllegalArgumentException", (RuntimeException,), {})
__all__ = [
"CharacterStyle",
"MetricAffectingSpan",
"BackgroundColorSpan",
"ForegroundColorSpan",
"StyleSpan",
"TypefaceSpan",
"AbsoluteSizeSpan",
"RelativeSizeSpan",
"ScaleXSpan",
"StrikethroughSpan",
"UnderlineSpan",
"SubscriptSpan",
"SuperscriptSpan",
"URLSpan",
"ClickableSpan",
"ImageSpan",
"AlignmentSpan",
"BulletSpan",
"QuoteSpan",
"LeadingMarginSpan",
"LeadingMarginSpan2",
"LineBackgroundSpan",
"LineHeightSpan",
"TabStopSpan",
"WrapTogetherSpan",
"ParagraphStyle",
"DrawableMarginSpan",
"IconMarginSpan",
"EasyEditSpan",
"SpellCheckSpan",
"SuggestionSpan",
"TextAppearanceSpan",
"LocaleSpan",
"ReplacementSpan",
"DynamicDrawableSpan",
"MaskFilterSpan",
"RasterizerSpan",
"ShadowStyleSpan",
"TtsSpan",
]
# ═══════════════════════════════════════════════════════════════
# CharacterStyle
# ═══════════════════════════════════════════════════════════════
class CharacterStyle(Stub):
"""CharacterStyle — 字符样式基类 (桌面存根)"""
def __init__(self):
super().__init__()
def setSpan(self, text: Any, start: int, end: int, flags: int) -> None:
"""设置 span 范围"""
pass
def getUnderlying(self) -> "CharacterStyle":
"""获取底层样式"""
return self
@staticmethod
def wrap(cs: "CharacterStyle") -> "CharacterStyle":
"""包装样式"""
return cs
def updateDrawState(self, tp: Any) -> None:
"""更新绘制状态"""
pass
def toString(self) -> str:
return f"{self.__class__.__name__}@CharacterStyle"
class MetricAffectingSpan(CharacterStyle):
"""MetricAffectingSpan — 影响度量的 Span"""
def __init__(self):
super().__init__()
def updateMeasureState(self, tp: Any) -> None:
"""更新度量状态"""
pass
# ═══════════════════════════════════════════════════════════════
# BackgroundColorSpan
# ═══════════════════════════════════════════════════════════════
class BackgroundColorSpan(CharacterStyle):
"""BackgroundColorSpan — 背景颜色 Span"""
def __init__(self, color: int = 0):
super().__init__()
self._color = color
def setColor(self, color: int) -> None:
"""设置背景颜色"""
self._color = color
def getBackgroundColor(self) -> int:
"""获取背景颜色"""
return self._color
def updateDrawState(self, tp: Any) -> None:
if hasattr(tp, 'bgColor'):
tp.bgColor = self._color
# ═══════════════════════════════════════════════════════════════
# ForegroundColorSpan
# ═══════════════════════════════════════════════════════════════
class ForegroundColorSpan(CharacterStyle):
"""ForegroundColorSpan — 前景颜色 Span"""
def __init__(self, color: int = 0):
super().__init__()
self._color = color
def setColor(self, color: int) -> None:
"""设置前景颜色"""
self._color = color
def getForegroundColor(self) -> int:
"""获取前景颜色"""
return self._color
def updateDrawState(self, tp: Any) -> None:
if hasattr(tp, 'color'):
tp.color = self._color
# ═══════════════════════════════════════════════════════════════
# StyleSpan
# ═══════════════════════════════════════════════════════════════
class StyleSpan(MetricAffectingSpan):
"""StyleSpan — 字体样式 Span"""
NORMAL = 0
BOLD = 1
ITALIC = 2
BOLD_ITALIC = 3
def __init__(self, style: int = NORMAL):
super().__init__()
self._style = style
def getStyle(self) -> int:
"""获取字体样式"""
return self._style
def updateDrawState(self, tp: Any) -> None:
if hasattr(tp, 'style'):
tp.style = self._style
def updateMeasureState(self, tp: Any) -> None:
if hasattr(tp, 'style'):
tp.style = self._style
# ═══════════════════════════════════════════════════════════════
# TypefaceSpan
# ═══════════════════════════════════════════════════════════════
class TypefaceSpan(MetricAffectingSpan):
"""TypefaceSpan — 字体 Span"""
def __init__(self, family: str = "sans-serif"):
super().__init__()
self._family = family
def getFamily(self) -> str:
"""获取字体名称"""
return self._family
def updateDrawState(self, tp: Any) -> None:
if hasattr(tp, 'typeface'):
tp.typeface = self._family
def updateMeasureState(self, tp: Any) -> None:
if hasattr(tp, 'typeface'):
tp.typeface = self._family
# ═══════════════════════════════════════════════════════════════
# AbsoluteSizeSpan
# ═══════════════════════════════════════════════════════════════
class AbsoluteSizeSpan(MetricAffectingSpan):
"""AbsoluteSizeSpan — 绝对字号 Span"""
def __init__(self, size: int = 0, dip: bool = False):
super().__init__()
self._size = size
self._dip = dip
def getSize(self) -> int:
"""获取字号"""
return self._size
def getDip(self) -> bool:
"""检查是否使用 dip 单位"""
return self._dip
def updateDrawState(self, tp: Any) -> None:
if hasattr(tp, 'textSize'):
tp.textSize = float(self._size)
def updateMeasureState(self, tp: Any) -> None:
if hasattr(tp, 'textSize'):
tp.textSize = float(self._size)
# ═══════════════════════════════════════════════════════════════
# RelativeSizeSpan
# ═══════════════════════════════════════════════════════════════
class RelativeSizeSpan(MetricAffectingSpan):
"""RelativeSizeSpan — 相对字号 Span"""
def __init__(self, proportion: float = 1.0):
super().__init__()
self._proportion = proportion
def getSizeChange(self) -> float:
"""获取字号变化比例"""
return self._proportion
def updateDrawState(self, tp: Any) -> None:
if hasattr(tp, 'textSize') and hasattr(tp, '_baseTextSize'):
tp.textSize = tp._baseTextSize * self._proportion
def updateMeasureState(self, tp: Any) -> None:
if hasattr(tp, 'textSize') and hasattr(tp, '_baseTextSize'):
tp.textSize = tp._baseTextSize * self._proportion
# ═══════════════════════════════════════════════════════════════
# ScaleXSpan
# ═══════════════════════════════════════════════════════════════
class ScaleXSpan(MetricAffectingSpan):
"""ScaleXSpan — X 轴缩放 Span"""
def __init__(self, scale_x: float = 1.0):
super().__init__()
self._scale_x = scale_x
def getScaleX(self) -> float:
"""获取 X 轴缩放比例"""
return self._scale_x
def updateDrawState(self, tp: Any) -> None:
if hasattr(tp, 'textScaleX'):
tp.textScaleX = self._scale_x
def updateMeasureState(self, tp: Any) -> None:
if hasattr(tp, 'textScaleX'):
tp.textScaleX = self._scale_x
# ═══════════════════════════════════════════════════════════════
# StrikethroughSpan / UnderlineSpan / SubscriptSpan / SuperscriptSpan
# ═══════════════════════════════════════════════════════════════
class StrikethroughSpan(CharacterStyle):
"""StrikethroughSpan — 删除线 Span"""
def __init__(self):
super().__init__()
def updateDrawState(self, tp: Any) -> None:
if hasattr(tp, 'strikethru'):
tp.strikethru = True
class UnderlineSpan(CharacterStyle):
"""UnderlineSpan — 下划线 Span"""
def __init__(self):
super().__init__()
def updateDrawState(self, tp: Any) -> None:
if hasattr(tp, 'underline'):
tp.underline = True
class SubscriptSpan(MetricAffectingSpan):
"""SubscriptSpan — 下标 Span"""
def __init__(self):
super().__init__()
def updateDrawState(self, tp: Any) -> None:
if hasattr(tp, 'subscript'):
tp.subscript = True
class SuperscriptSpan(MetricAffectingSpan):
"""SuperscriptSpan — 上标 Span"""
def __init__(self):
super().__init__()
def updateDrawState(self, tp: Any) -> None:
if hasattr(tp, 'superscript'):
tp.superscript = True
# ═══════════════════════════════════════════════════════════════
# URLSpan / ClickableSpan
# ═══════════════════════════════════════════════════════════════
class URLSpan(CharacterStyle):
"""URLSpan — 超链接 Span"""
def __init__(self, url: str = ""):
super().__init__()
self._url = url
def getURL(self) -> str:
"""获取 URL"""
return self._url
def updateDrawState(self, tp: Any) -> None:
if hasattr(tp, 'color'):
tp.color = 0xFF0000FF # blue
if hasattr(tp, 'underline'):
tp.underline = True
def onClick(self, view: Any) -> None:
"""点击事件"""
pass
class ClickableSpan(CharacterStyle):
"""ClickableSpan — 可点击 Span"""
def __init__(self):
super().__init__()
def onClick(self, view: Any) -> None:
"""点击事件"""
pass
def updateDrawState(self, tp: Any) -> None:
if hasattr(tp, 'color'):
tp.color = 0xFF0000FF
if hasattr(tp, 'underline'):
tp.underline = True
# ═══════════════════════════════════════════════════════════════
# ImageSpan
# ═══════════════════════════════════════════════════════════════
class ImageSpan(CharacterStyle):
"""ImageSpan — 图片 Span"""
def __init__(self, drawable: Any = None, source: str = "", vertical_alignment: int = 0):
super().__init__()
self._drawable = drawable
self._source = source
self._vertical_alignment = vertical_alignment
def getDrawable(self) -> Any:
"""获取 Drawable"""
return self._drawable
def getSource(self) -> str:
"""获取资源源"""
return self._source
def getContentUri(self) -> Optional[str]:
"""获取内容 URI"""
return None
def draw(self, canvas: Any, text: str, x: int, y: int, top: int, bottom: int) -> None:
"""绘制图片"""
if self._drawable and hasattr(self._drawable, 'draw'):
self._drawable.draw(canvas)
def toString(self) -> str:
return f"ImageSpan(source={self._source})"
# ═══════════════════════════════════════════════════════════════
# AlignmentSpan
# ═══════════════════════════════════════════════════════════════
class AlignmentSpan(CharacterStyle):
"""AlignmentSpan — 对齐 Span"""
class Standard(CharacterStyle):
"""标准对齐实现"""
def __init__(self, alignment: int):
super().__init__()
self._alignment = alignment
def getAlignment(self) -> int:
return self._alignment
def updateDrawState(self, tp: Any) -> None:
if hasattr(tp, 'alignment'):
tp.alignment = self._alignment
def __init__(self, alignment: int = 0):
super().__init__()
self._alignment = alignment
def getAlignment(self) -> int:
"""获取对齐方式"""
return self._alignment
def updateDrawState(self, tp: Any) -> None:
if hasattr(tp, 'alignment'):
tp.alignment = self._alignment
# ═══════════════════════════════════════════════════════════════
# BulletSpan
# ═══════════════════════════════════════════════════════════════
class BulletSpan(CharacterStyle):
"""BulletSpan — 项目符号 Span"""
STANDARD_GAP_WIDTH = 2
def __init__(self, leading_margin: int = 0, gap_width: int = STANDARD_GAP_WIDTH,
bullet_radius: int = 4, color: int = 0xFF000000):
super().__init__()
self._leading_margin = leading_margin
self._gap_width = gap_width
self._bullet_radius = bullet_radius
self._color = color
def getLeadingMargin(self) -> int:
"""获取前导边距"""
return self._leading_margin
def getGapWidth(self) -> int:
"""获取间隙宽度"""
return self._gap_width
def getBulletRadius(self) -> int:
"""获取项目符号半径"""
return self._bullet_radius
def getColor(self) -> int:
"""获取颜色"""
return self._color
def updateDrawState(self, tp: Any) -> None:
pass
def drawLeadingMargin(self, canvas: Any, paint: Any, x: int, dir_: int,
top: int, baseline: int, bottom: int, text: str,
start: int, end: int, first: bool, margin: int) -> None:
"""绘制前导边距中的项目符号"""
pass
# ═══════════════════════════════════════════════════════════════
# QuoteSpan
# ═══════════════════════════════════════════════════════════════
class QuoteSpan(CharacterStyle):
"""QuoteSpan — 引用 Span"""
STANDARD_GAP_WIDTH = 2
STANDARD_COLOR = 0xFF0000FF
def __init__(self, color: int = STANDARD_COLOR, gap_width: int = STANDARD_GAP_WIDTH, stripe_width: int = 2):
super().__init__()
self._color = color
self._gap_width = gap_width
self._stripe_width = stripe_width
def getColor(self) -> int:
"""获取引用颜色"""
return self._color
def getGapWidth(self) -> int:
"""获取间隙宽度"""
return self._gap_width
def getStripeWidth(self) -> int:
"""获取条纹宽度"""
return self._stripe_width
def updateDrawState(self, tp: Any) -> None:
pass
def drawLeadingMargin(self, canvas: Any, paint: Any, x: int, dir_: int,
top: int, baseline: int, bottom: int, text: str,
start: int, end: int, first: bool, margin: int) -> None:
"""绘制引用条纹"""
pass
# ═══════════════════════════════════════════════════════════════
# LeadingMarginSpan / LeadingMarginSpan2
# ═══════════════════════════════════════════════════════════════
class LeadingMarginSpan(CharacterStyle):
"""LeadingMarginSpan — 前导边距 Span"""
def __init__(self):
super().__init__()
def getLeadingMargin(self, first: bool) -> int:
"""获取前导边距"""
return 0
def drawLeadingMargin(self, canvas: Any, paint: Any, x: int, dir_: int,
top: int, baseline: int, bottom: int, text: str,
start: int, end: int, first: bool, margin: int) -> None:
"""绘制前导边距"""
pass
class LeadingMarginSpan2(LeadingMarginSpan):
"""LeadingMarginSpan2 — 支持行数限制的前导边距 Span"""
def __init__(self):
super().__init__()
def getLeadingMarginLineCount(self) -> int:
"""获取前导边距行数"""
return 1
# ═══════════════════════════════════════════════════════════════
# LineBackgroundSpan / LineHeightSpan
# ═══════════════════════════════════════════════════════════════
class LineBackgroundSpan(CharacterStyle):
"""LineBackgroundSpan — 行背景 Span"""
def __init__(self):
super().__init__()
def drawBackground(self, canvas: Any, paint: Any, left: int, right: int,
top: int, baseline: int, bottom: int, text: str,
start: int, end: int, line_num: int) -> None:
"""绘制行背景"""
pass
class LineHeightSpan(CharacterStyle):
"""LineHeightSpan — 行高 Span"""
class WithDensity(CharacterStyle):
"""带密度参数的行高实现"""
def __init__(self):
super().__init__()
def chooseHeight(self, text: str, start: int, end: int, spanstart: int,
spanend: int, height: List[int], fontMetrics: Any) -> None:
pass
def __init__(self):
super().__init__()
def chooseHeight(self, text: str, start: int, end: int, spanstart: int,
spanend: int, height: List[int], fontMetrics: Any) -> None:
"""选择行高"""
pass
@staticmethod
def increaseHeight(height: List[int], increase: int) -> None:
"""增加高度"""
if height:
height[0] = height[0] + increase
# ═══════════════════════════════════════════════════════════════
# TabStopSpan / WrapTogetherSpan / ParagraphStyle
# ═══════════════════════════════════════════════════════════════
class TabStopSpan(CharacterStyle):
"""TabStopSpan — 制表符停靠 Span"""
class Standard(CharacterStyle):
"""标准制表符停靠实现"""
def __init__(self, tab_stop: int = 40):
super().__init__()
self._tab_stop = tab_stop
def getTabStop(self) -> int:
return self._tab_stop
def __init__(self, tab_stop: int = 40):
super().__init__()
self._tab_stop = tab_stop
def getTabStop(self) -> int:
"""获取制表符停靠位置"""
return self._tab_stop
class WrapTogetherSpan(CharacterStyle):
"""WrapTogetherSpan — 一起换行 Span"""
def __init__(self):
super().__init__()
class ParagraphStyle(Stub):
"""ParagraphStyle — 段落样式标记接口"""
def __init__(self):
super().__init__()
# ═══════════════════════════════════════════════════════════════
# DrawableMarginSpan / IconMarginSpan
# ═══════════════════════════════════════════════════════════════
class DrawableMarginSpan(CharacterStyle):
"""DrawableMarginSpan — 可绘制边距 Span"""
def __init__(self, drawable: Any = None, pad: int = 0):
super().__init__()
self._drawable = drawable
self._pad = pad
class IconMarginSpan(CharacterStyle):
"""IconMarginSpan — 图标边距 Span"""
def __init__(self, bitmap: Any = None, pad: int = 0):
super().__init__()
self._bitmap = bitmap
self._pad = pad
# ═══════════════════════════════════════════════════════════════
# EasyEditSpan / SpellCheckSpan
# ═══════════════════════════════════════════════════════════════
class EasyEditSpan(CharacterStyle):
"""EasyEditSpan — 简易编辑 Span"""
def __init__(self):
super().__init__()
class SpellCheckSpan(CharacterStyle):
"""SpellCheckSpan — 拼写检查 Span"""
def __init__(self, spell_checking: bool = True):
super().__init__()
self._spell_checking = spell_checking
def isSpellCheckEnabled(self) -> bool:
"""检查拼写检查是否启用"""
return self._spell_checking
def setSpellCheckEnabled(self, enabled: bool) -> None:
"""设置拼写检查启用"""
self._spell_checking = enabled
# ═══════════════════════════════════════════════════════════════
# SuggestionSpan
# ═══════════════════════════════════════════════════════════════
class SuggestionSpan(CharacterStyle):
"""SuggestionSpan — 建议 Span"""
FLAG_EASY_CORRECT = 0x0001
FLAG_MISSPELLED = 0x0002
FLAG_AUTO_CORRECTION = 0x0004
FLAG_GRAMMAR_ERROR = 0x0008
FLAG_PERSONAL_NAME = 0x0010
FLAG_COMPATIBILITY = 0x0020
SUGGESTIONS_MAX_SIZE = 5
def __init__(self, locale: Optional[Any] = None, suggestions: Optional[List[str]] = None,
flags: int = 0, underline_color: int = 0):
super().__init__()
self._locale = locale
self._suggestions = suggestions or []
self._flags = flags
self._underline_color = underline_color
def getLocale(self) -> Optional[Any]:
"""获取区域设置"""
return self._locale
def getSuggestions(self) -> List[str]:
"""获取建议列表"""
return self._suggestions.copy()
def getUnderlineColor(self) -> int:
"""获取下划线颜色"""
return self._underline_color
def setUnderlineColor(self, color: int) -> None:
"""设置下划线颜色"""
self._underline_color = color
def getFlags(self) -> int:
"""获取标志"""
return self._flags
def setFlags(self, flags: int) -> None:
"""设置标志"""
self._flags = flags
@staticmethod
def getSuggestionsFromContext(context: Any, locale: Any, query: str,
max_results: int = SUGGESTIONS_MAX_SIZE) -> List[str]:
"""从上下文中获取建议"""
return []
# ═══════════════════════════════════════════════════════════════
# TextAppearanceSpan
# ═══════════════════════════════════════════════════════════════
class TextAppearanceSpan(MetricAffectingSpan):
"""TextAppearanceSpan — 文字外观 Span"""
def __init__(self, context: Any = None, appearance_id: int = 0,
family: str = "sans-serif", text_size: Optional[int] = None,
text_color: Optional[int] = None, link_text_color: Optional[int] = None):
super().__init__()
self._family = family
self._text_size = text_size
self._text_color = text_color
self._link_text_color = link_text_color
def getFamily(self) -> str:
"""获取字体名称"""
return self._family
def getTextSize(self) -> Optional[int]:
"""获取字号"""
return self._text_size
def getTextColor(self) -> Optional[int]:
"""获取文字颜色"""
return self._text_color
def getTextColorLink(self) -> Optional[int]:
"""获取链接文字颜色"""
return self._link_text_color
def getLinkTextColor(self) -> Optional[int]:
"""获取链接文字颜色"""
return self._link_text_color
def updateDrawState(self, tp: Any) -> None:
if self._text_color is not None and hasattr(tp, 'color'):
tp.color = self._text_color
if self._text_size is not None and hasattr(tp, 'textSize'):
tp.textSize = float(self._text_size)
if hasattr(tp, 'typeface'):
tp.typeface = self._family
def updateMeasureState(self, tp: Any) -> None:
if self._text_size is not None and hasattr(tp, 'textSize'):
tp.textSize = float(self._text_size)
# ═══════════════════════════════════════════════════════════════
# LocaleSpan
# ═══════════════════════════════════════════════════════════════
class LocaleSpan(MetricAffectingSpan):
"""LocaleSpan — 区域设置 Span"""
def __init__(self, locale: Any = None):
super().__init__()
self._locale = locale
def getLocale(self) -> Any:
"""获取区域设置"""
return self._locale
def updateDrawState(self, tp: Any) -> None:
pass
def updateMeasureState(self, tp: Any) -> None:
pass
# ═══════════════════════════════════════════════════════════════
# ReplacementSpan
# ═══════════════════════════════════════════════════════════════
class ReplacementSpan(CharacterStyle):
"""ReplacementSpan — 替换 Span"""
def __init__(self):
super().__init__()
def draw(self, canvas: Any, text: str, start: int, end: int, x: float,
top: int, y: float, bottom: int, paint: Any) -> None:
"""绘制替换内容"""
pass
def getSize(self, paint: Any, text: str, start: int, end: int,
fontMetrics: Optional[Any]) -> int:
"""获取尺寸"""
return 0
def updateMeasureState(self, tp: Any) -> None:
pass
# ═══════════════════════════════════════════════════════════════
# DynamicDrawableSpan
# ═══════════════════════════════════════════════════════════════
class DynamicDrawableSpan(ReplacementSpan):
"""DynamicDrawableSpan — 动态可绘制 Span"""
ALIGN_BOTTOM = 0
ALIGN_BASELINE = 1
ALIGN_CENTER = 2
def __init__(self, vertical_alignment: int = ALIGN_BOTTOM):
super().__init__()
self._vertical_alignment = vertical_alignment
def getDrawable(self) -> Any:
"""获取可绘制对象"""
return None
def draw(self, canvas: Any, text: str, start: int, end: int, x: float,
top: int, y: float, bottom: int, paint: Any) -> None:
drawable = self.getDrawable()
if drawable:
pass
def getSize(self, paint: Any, text: str, start: int, end: int,
fontMetrics: Optional[Any]) -> int:
drawable = self.getDrawable()
if drawable and hasattr(drawable, 'getIntrinsicWidth'):
return drawable.getIntrinsicWidth()
return 0
# ═══════════════════════════════════════════════════════════════
# MaskFilterSpan / RasterizerSpan / ShadowStyleSpan
# ═══════════════════════════════════════════════════════════════
class MaskFilterSpan(CharacterStyle):
"""MaskFilterSpan — 遮罩滤镜 Span"""
def __init__(self, filter_: Any = None):
super().__init__()
self._filter = filter_
def getMaskFilter(self) -> Any:
"""获取遮罩滤镜"""
return self._filter
def updateDrawState(self, tp: Any) -> None:
if hasattr(tp, 'maskFilter'):
tp.maskFilter = self._filter
class RasterizerSpan(CharacterStyle):
"""RasterizerSpan — 光栅化 Span"""
def __init__(self, rasterizer: Any = None):
super().__init__()
self._rasterizer = rasterizer
def getRasterizer(self) -> Any:
"""获取光栅化器"""
return self._rasterizer
def updateDrawState(self, tp: Any) -> None:
if hasattr(tp, 'rasterizer'):
tp.rasterizer = self._rasterizer
class ShadowStyleSpan(CharacterStyle):
"""ShadowStyleSpan — 阴影样式 Span"""
def __init__(self, radius: float = 1.0, dx: float = 0, dy: float = 0, color: int = 0):
super().__init__()
self._radius = radius
self._dx = dx
self._dy = dy
self._color = color
def updateDrawState(self, tp: Any) -> None:
if hasattr(tp, 'setShadowLayer'):
tp.setShadowLayer(self._radius, self._dx, self._dy, self._color)
# ═══════════════════════════════════════════════════════════════
# TtsSpan
# ═══════════════════════════════════════════════════════════════
class TtsSpan(CharacterStyle):
"""TtsSpan — 文本转语音 Span"""
TYPE_DATE = "android.type.date"
TYPE_DELIMITER = "android.type.delimiter"
TYPE_DIGITS = "android.type.digits"
TYPE_ELECTRONIC = "android.type.electronic"
TYPE_FRACTION = "android.type.fraction"
TYPE_MEASURE = "android.type.measure"
TYPE_MONEY = "android.type.money"
TYPE_NUMBER = "android.type.number"
TYPE_ORDINAL = "android.type.ordinal"
TYPE_PERCENTAGE = "android.type.percentage"
TYPE_TELEPHONE = "android.type.telephone"
TYPE_TEXT = "android.type.text"
TYPE_TIME = "android.type.time"
TYPE_VERBATIM = "android.type.verbatim"
ARG_TEXT = "android.arg.text"
ARG_QUANTITY = "android.arg.quantity"
ARG_MINUTES = "android.arg.minutes"
ARG_HOURS = "android.arg.hours"
ARG_DAY = "android.arg.day"
ARG_MONTH = "android.arg.month"
ARG_YEAR = "android.arg.year"
ARG_WEEKDAY = "android.arg.weekday"
ARG_COUNTRY_CODE = "android.arg.country_code"
ARG_NUMBER_PARTS = "android.arg.number_parts"
ARG_NUMBER_TYPE = "android.arg.number_type"
ARG_NUMBER_GROUP = "android.arg.number_group"
ARG_MONEY = "android.arg.money"
ARG_CURRENCY = "android.arg.currency"
ARG_AMOUNT = "android.arg.amount"
ARG_FRACTION_DENOMINATOR = "android.arg.fraction_denominator"
ARG_FRACTION_NUMERATOR = "android.arg.fraction_numerator"
ARG_FRACTION_TYPE = "android.arg.fraction_type"
ARG_INTEGER_PART = "android.arg.integer_part"
def __init__(self, type_: str = TYPE_TEXT, args: Optional[Dict[str, str]] = None):
super().__init__()
self._type = type_
self._args = args or {}
def getType(self) -> str:
"""获取 TTS 类型"""
return self._type
def getArgs(self) -> Dict[str, str]:
"""获取参数"""
return self._args.copy()
def toString(self) -> str:
return f"TtsSpan(type={self._type}, args={self._args})"