feat(epub): overhaul border system to support individual sides and radii (#44)
- Refactored `BlockStyle` to replace unified border/radius fields with explicit properties for all four sides and corners. - Overhauled `CssParser` to correctly handle CSS border shorthands (`border-bottom`, `border-width`, etc.) and multi-value `border-radius`. - Implemented `drawCssBorders` custom modifier to render side-specific borders, styles (dashed/dotted), and background clipping. - Updated `Paginator` measurement logic to calculate block height and splitting points based on individual side widths.
This commit is contained in:
parent
68c4611187
commit
dff236fa7f
6 changed files with 434 additions and 206 deletions
|
|
@ -51,28 +51,34 @@ data class BlockStyle(
|
|||
@ProtoNumber(4) @Serializable(with = DpSerializer::class) val maxWidth: Dp = Dp.Unspecified,
|
||||
@ProtoNumber(5) @Serializable(with = DpSerializer::class) val height: Dp = Dp.Unspecified,
|
||||
@ProtoNumber(6) @Serializable(with = ColorSerializer::class) val backgroundColor: Color = Color.Unspecified,
|
||||
@ProtoNumber(7) val border: BorderStyle? = null,
|
||||
@ProtoNumber(8) val listStyleType: String? = null,
|
||||
@ProtoNumber(9) val listStyleImage: String? = null,
|
||||
@ProtoNumber(10) val pageBreakInsideAvoid: Boolean = false,
|
||||
@ProtoNumber(11) val pageBreakAfterAvoid: Boolean = false,
|
||||
@ProtoNumber(12) val boxSizing: String? = null,
|
||||
@ProtoNumber(13) val float: String? = null,
|
||||
@ProtoNumber(14) val clear: String? = null,
|
||||
@ProtoNumber(15) val position: String? = null,
|
||||
@ProtoNumber(16) @Serializable(with = DpSerializer::class) val top: Dp = Dp.Unspecified,
|
||||
@ProtoNumber(17) @Serializable(with = DpSerializer::class) val right: Dp = Dp.Unspecified,
|
||||
@ProtoNumber(18) @Serializable(with = DpSerializer::class) val bottom: Dp = Dp.Unspecified,
|
||||
@ProtoNumber(19) @Serializable(with = DpSerializer::class) val left: Dp = Dp.Unspecified,
|
||||
@ProtoNumber(20) val display: String? = null,
|
||||
@ProtoNumber(21) val flexDirection: String? = null,
|
||||
@ProtoNumber(22) val justifyContent: String? = null,
|
||||
@ProtoNumber(23) val alignItems: String? = null,
|
||||
@ProtoNumber(24) val horizontalAlign: String? = null,
|
||||
@ProtoNumber(25) val filter: String? = null,
|
||||
@ProtoNumber(26) val borderCollapse: String? = null,
|
||||
@ProtoNumber(27) @Serializable(with = DpSerializer::class) val borderSpacing: Dp = 0.dp,
|
||||
@ProtoNumber(28) @Serializable(with = DpSerializer::class) val borderRadius: Dp = 0.dp
|
||||
@ProtoNumber(7) val borderTop: BorderStyle? = null,
|
||||
@ProtoNumber(8) val borderRight: BorderStyle? = null,
|
||||
@ProtoNumber(9) val borderBottom: BorderStyle? = null,
|
||||
@ProtoNumber(10) val borderLeft: BorderStyle? = null,
|
||||
@ProtoNumber(11) val listStyleType: String? = null,
|
||||
@ProtoNumber(12) val listStyleImage: String? = null,
|
||||
@ProtoNumber(13) val pageBreakInsideAvoid: Boolean = false,
|
||||
@ProtoNumber(14) val pageBreakAfterAvoid: Boolean = false,
|
||||
@ProtoNumber(15) val boxSizing: String? = null,
|
||||
@ProtoNumber(16) val float: String? = null,
|
||||
@ProtoNumber(17) val clear: String? = null,
|
||||
@ProtoNumber(18) val position: String? = null,
|
||||
@ProtoNumber(19) @Serializable(with = DpSerializer::class) val top: Dp = Dp.Unspecified,
|
||||
@ProtoNumber(20) @Serializable(with = DpSerializer::class) val right: Dp = Dp.Unspecified,
|
||||
@ProtoNumber(21) @Serializable(with = DpSerializer::class) val bottom: Dp = Dp.Unspecified,
|
||||
@ProtoNumber(22) @Serializable(with = DpSerializer::class) val left: Dp = Dp.Unspecified,
|
||||
@ProtoNumber(23) val display: String? = null,
|
||||
@ProtoNumber(24) val flexDirection: String? = null,
|
||||
@ProtoNumber(25) val justifyContent: String? = null,
|
||||
@ProtoNumber(26) val alignItems: String? = null,
|
||||
@ProtoNumber(27) val horizontalAlign: String? = null,
|
||||
@ProtoNumber(28) val filter: String? = null,
|
||||
@ProtoNumber(29) val borderCollapse: String? = null,
|
||||
@ProtoNumber(30) @Serializable(with = DpSerializer::class) val borderTopLeftRadius: Dp = 0.dp,
|
||||
@ProtoNumber(31) @Serializable(with = DpSerializer::class) val borderTopRightRadius: Dp = 0.dp,
|
||||
@ProtoNumber(32) @Serializable(with = DpSerializer::class) val borderBottomRightRadius: Dp = 0.dp,
|
||||
@ProtoNumber(33) @Serializable(with = DpSerializer::class) val borderBottomLeftRadius: Dp = 0.dp,
|
||||
@ProtoNumber(34) @Serializable(with = DpSerializer::class) val borderSpacing: Dp = 0.dp
|
||||
) {
|
||||
fun merge(other: BlockStyle): BlockStyle {
|
||||
return BlockStyle(
|
||||
|
|
@ -92,7 +98,14 @@ data class BlockStyle(
|
|||
maxWidth = if (other.maxWidth != Dp.Unspecified) other.maxWidth else this.maxWidth,
|
||||
height = if (other.height != Dp.Unspecified) other.height else this.height,
|
||||
backgroundColor = if (other.backgroundColor.isSpecified) other.backgroundColor else this.backgroundColor,
|
||||
border = other.border ?: this.border,
|
||||
borderTop = other.borderTop ?: this.borderTop,
|
||||
borderRight = other.borderRight ?: this.borderRight,
|
||||
borderBottom = other.borderBottom ?: this.borderBottom,
|
||||
borderLeft = other.borderLeft ?: this.borderLeft,
|
||||
borderTopLeftRadius = if (other.borderTopLeftRadius != 0.dp) other.borderTopLeftRadius else this.borderTopLeftRadius,
|
||||
borderTopRightRadius = if (other.borderTopRightRadius != 0.dp) other.borderTopRightRadius else this.borderTopRightRadius,
|
||||
borderBottomRightRadius = if (other.borderBottomRightRadius != 0.dp) other.borderBottomRightRadius else this.borderBottomRightRadius,
|
||||
borderBottomLeftRadius = if (other.borderBottomLeftRadius != 0.dp) other.borderBottomLeftRadius else this.borderBottomLeftRadius,
|
||||
listStyleType = other.listStyleType ?: this.listStyleType,
|
||||
listStyleImage = other.listStyleImage ?: this.listStyleImage,
|
||||
pageBreakInsideAvoid = this.pageBreakInsideAvoid || other.pageBreakInsideAvoid,
|
||||
|
|
@ -112,8 +125,7 @@ data class BlockStyle(
|
|||
horizontalAlign = other.horizontalAlign ?: this.horizontalAlign,
|
||||
filter = other.filter ?: this.filter,
|
||||
borderCollapse = other.borderCollapse ?: this.borderCollapse,
|
||||
borderSpacing = if (other.borderSpacing != 0.dp) other.borderSpacing else this.borderSpacing,
|
||||
borderRadius = if (other.borderRadius != 0.dp) other.borderRadius else this.borderRadius
|
||||
borderSpacing = if (other.borderSpacing != 0.dp) other.borderSpacing else this.borderSpacing
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue