summaryrefslogtreecommitdiff
path: root/src/lib/edje/edje_calc.c
diff options
context:
space:
mode:
authorDaniel Hirt <hirt.danny@gmail.com>2017-10-15 17:55:20 +0300
committerCedric BAIL <cedric@osg.samsung.com>2017-11-10 10:30:04 -0800
commitc7b2372ffb35cc51415f943b7ff2895d245362bc (patch)
treec16a1438d36a17013c861e6e2f8acf7c82408cbf /src/lib/edje/edje_calc.c
parent58ce1d654b0d4ead58bba384b1e1edd5b605bc4e (diff)
Edje: move textblock handling to a separate source
Signed-off-by: Cedric BAIL <cedric@osg.samsung.com>
Diffstat (limited to '')
-rw-r--r--src/lib/edje/edje_calc.c577
1 files changed, 0 insertions, 577 deletions
diff --git a/src/lib/edje/edje_calc.c b/src/lib/edje/edje_calc.c
index 3cfa5dc924..1442cb8f14 100644
--- a/src/lib/edje/edje_calc.c
+++ b/src/lib/edje/edje_calc.c
@@ -1453,583 +1453,6 @@ _edje_part_recalc_single_step(Edje_Part_Description_Common *desc,
1453 } 1453 }
1454} 1454}
1455 1455
1456static double
1457_edje_part_recalc_single_textblock_scale_range_adjust(Edje_Part_Description_Text *chosen_desc, double base_scale, double scale)
1458{
1459 double size, min, max;
1460
1461 if (chosen_desc->text.size == 0)
1462 return scale;
1463
1464 min = base_scale * chosen_desc->text.size_range_min;
1465 max = chosen_desc->text.size_range_max * base_scale;
1466 size = chosen_desc->text.size * scale;
1467
1468 if ((size > max) && (max > 0))
1469 scale = max / (double)chosen_desc->text.size;
1470 else if (size < min)
1471 scale = min / (double)chosen_desc->text.size;
1472
1473 return scale;
1474}
1475
1476/*
1477 * Legacy function for min/max calculation of textblock part.
1478 * It can't calculate min/max properly in many cases.
1479 *
1480 * To keep backward compatibility, it will be used for old version of EDJ files.
1481 * You can't see proper min/max result accroding to documents with this function.
1482 */
1483static void
1484_edje_part_recalc_single_textblock_min_max_calc_legacy(Edje_Real_Part *ep,
1485 Edje_Part_Description_Text *chosen_desc,
1486 Edje_Calc_Params *params,
1487 int *minw, int *minh,
1488 int *maxw, int *maxh)
1489{
1490 Evas_Coord tw, th, ins_l, ins_r, ins_t, ins_b;
1491
1492 /* Legacy code for Textblock min/max calculation */
1493 if ((chosen_desc->text.min_x) || (chosen_desc->text.min_y))
1494 {
1495 int mw = 0, mh = 0;
1496
1497 tw = th = 0;
1498 if (!chosen_desc->text.min_x)
1499 {
1500 efl_gfx_size_set(ep->object, EINA_SIZE2D(TO_INT(params->eval.w), TO_INT(params->eval.h)));
1501 efl_canvas_text_size_formatted_get(ep->object, &tw, &th);
1502 }
1503 else
1504 evas_object_textblock_size_native_get(ep->object, &tw, &th);
1505 evas_object_textblock_style_insets_get(ep->object, &ins_l,
1506 &ins_r, &ins_t, &ins_b);
1507 mw = ins_l + tw + ins_r;
1508 mh = ins_t + th + ins_b;
1509 if (minw && chosen_desc->text.min_x)
1510 {
1511 if (mw > *minw) *minw = mw;
1512 }
1513 if (minh && chosen_desc->text.min_y)
1514 {
1515 if (mh > *minh) *minh = mh;
1516 }
1517 }
1518
1519 if ((chosen_desc->text.max_x) || (chosen_desc->text.max_y))
1520 {
1521 int mw = 0, mh = 0;
1522
1523 tw = th = 0;
1524 if (!chosen_desc->text.max_x)
1525 {
1526 efl_gfx_size_set(ep->object, EINA_SIZE2D(TO_INT(params->eval.w), TO_INT(params->eval.h)));
1527 efl_canvas_text_size_formatted_get(ep->object, &tw, &th);
1528 }
1529 else
1530 evas_object_textblock_size_native_get(ep->object, &tw, &th);
1531 evas_object_textblock_style_insets_get(ep->object, &ins_l, &ins_r,
1532 &ins_t, &ins_b);
1533 mw = ins_l + tw + ins_r;
1534 mh = ins_t + th + ins_b;
1535 if (maxw && chosen_desc->text.max_x)
1536 {
1537 if (mw > *maxw) *maxw = mw;
1538 if (minw && (*maxw < *minw)) *maxw = *minw;
1539 }
1540 if (maxh && chosen_desc->text.max_y)
1541 {
1542 if (mh > *maxh) *maxh = mh;
1543 if (minh && (*maxh < *minh)) *maxh = *minh;
1544 }
1545 }
1546}
1547
1548static void
1549_edje_part_recalc_single_textblock_min_max_calc(Edje_Real_Part *ep,
1550 Edje_Part_Description_Text *chosen_desc,
1551 Edje_Calc_Params *params,
1552 int *minw, int *minh,
1553 int *maxw, int *maxh)
1554{
1555 Evas_Coord tw, th, ins_l, ins_r, ins_t, ins_b;
1556 Evas_Coord min_calc_w = 0, min_calc_h = 0;
1557
1558 /* min_calc_* values need to save calculated minumum size
1559 * for maximum size calculation */
1560 if (minw) min_calc_w = *minw;
1561 if (minh) min_calc_h = *minh;
1562
1563 if ((chosen_desc->text.min_x) || (chosen_desc->text.min_y))
1564 {
1565 evas_object_textblock_style_insets_get(ep->object, &ins_l,
1566 &ins_r, &ins_t, &ins_b);
1567
1568 tw = th = 0;
1569 if (!chosen_desc->text.min_x)
1570 {
1571 /* text.min: 0 1
1572 * text.max: X X */
1573 int temp_h = TO_INT(params->eval.h);
1574 int temp_w = TO_INT(params->eval.w);
1575
1576 if (min_calc_w > temp_w)
1577 temp_w = min_calc_w;
1578 if ((!chosen_desc->text.max_x) &&
1579 maxw && (*maxw > -1) && (*maxw < temp_w))
1580 temp_w = *maxw;
1581
1582 if (chosen_desc->text.max_y)
1583 {
1584 /* text.min: 0 1
1585 * text.max: X 1 */
1586 temp_h = INT_MAX / 10000;
1587 }
1588 else if (maxh && (*maxh > TO_INT(params->eval.h)))
1589 {
1590 /* text.min: 0 1
1591 * text.max: X 0
1592 * And there is a limit for height. */
1593 temp_h = *maxh;
1594 }
1595
1596 /* If base width for calculation is 0,
1597 * don't get meaningless height for multiline */
1598 if (temp_w > 0)
1599 {
1600 efl_gfx_size_set(ep->object, EINA_SIZE2D(temp_w, temp_h));
1601 efl_canvas_text_size_formatted_get(ep->object, &tw, &th);
1602
1603 tw += ins_l + ins_r;
1604 th += ins_t + ins_b;
1605 }
1606 else
1607 {
1608 efl_canvas_text_size_native_get(ep->object, NULL, &th);
1609
1610 th += ins_t + ins_b;
1611 }
1612 }
1613 else
1614 {
1615 /* text.min: 1 X
1616 * text.max: X X */
1617 if (chosen_desc->text.min_y && (!chosen_desc->text.max_x) &&
1618 maxw && (*maxw > -1))
1619 {
1620 /* text.min: 1 1
1621 * text.max: 0 X */
1622 int temp_w, temp_h;
1623
1624 temp_w = *maxw;
1625 temp_h = INT_MAX / 10000;
1626
1627 if (min_calc_w > temp_w)
1628 temp_w = min_calc_w;
1629
1630 if ((!chosen_desc->text.max_y) && maxh && (*maxh > -1))
1631 {
1632 /* text.min: 1 1
1633 * text.max: 0 0
1634 * There is limit for height. */
1635 temp_h = *maxh;
1636 }
1637
1638 efl_gfx_size_set(ep->object, EINA_SIZE2D(temp_w, temp_h));
1639 efl_canvas_text_size_formatted_get(ep->object, &tw, &th);
1640
1641 tw += ins_l + ins_r;
1642 th += ins_t + ins_b;
1643
1644 /* If base width for calculation is 0,
1645 * don't get meaningless height for multiline */
1646 if (temp_w <= 0)
1647 {
1648 efl_canvas_text_size_native_get(ep->object, NULL, &th);
1649
1650 th += ins_t + ins_b;
1651 }
1652 }
1653 else
1654 {
1655 /* text.min: 1 X
1656 * text.max: 1 X
1657 * Or,
1658 * text.min: 1 X
1659 * text.max: 0 X without max width.
1660 * It is a singleline Textblock. */
1661 efl_canvas_text_size_native_get(ep->object, &tw, &th);
1662
1663 tw += ins_l + ins_r;
1664 th += ins_t + ins_b;
1665
1666 if (!chosen_desc->text.max_x &&
1667 (maxw && (*maxw > -1) && (*maxw < tw)))
1668 {
1669 /* text.min: 1 0
1670 * text.max: 0 X */
1671 tw = *maxw;
1672 }
1673 }
1674 }
1675
1676 if (tw > min_calc_w) min_calc_w = tw;
1677 if (th > min_calc_h) min_calc_h = th;
1678 if (chosen_desc->text.min_x && minw) *minw = min_calc_w;
1679 if (chosen_desc->text.min_y && minh) *minh = min_calc_h;
1680 }
1681
1682 if ((chosen_desc->text.max_x) || (chosen_desc->text.max_y))
1683 {
1684 evas_object_textblock_style_insets_get(ep->object, &ins_l, &ins_r,
1685 &ins_t, &ins_b);
1686
1687 tw = th = 0;
1688 if (!chosen_desc->text.max_x)
1689 {
1690 /* text.min: X X
1691 * text.max: 0 1 */
1692 int temp_w, temp_h;
1693
1694 if (chosen_desc->text.min_y)
1695 {
1696 /* text.min: X 1
1697 * text.max: 0 1
1698 * Already calculated in text for height. */
1699 tw = TO_INT(params->eval.w);
1700 if (min_calc_w > tw)
1701 tw = min_calc_w;
1702
1703 th = min_calc_h;
1704 }
1705 else
1706 {
1707 /* text.min: X 0
1708 * text.max: 0 1 */
1709 temp_w = TO_INT(params->eval.w);
1710 temp_h = TO_INT(params->eval.h);
1711
1712 if (min_calc_w > temp_w)
1713 temp_w = min_calc_w;
1714 if (maxw && (*maxw > -1) && (*maxw < temp_w))
1715 temp_w = *maxw;
1716 if (min_calc_h > temp_h)
1717 temp_h = min_calc_h;
1718
1719 /* If base width for calculation is 0,
1720 * don't get meaningless height for multiline */
1721 if (temp_w > 0)
1722 {
1723 efl_gfx_size_set(ep->object, EINA_SIZE2D(temp_w, temp_h));
1724 efl_canvas_text_size_formatted_get(ep->object, &tw, &th);
1725
1726 tw += ins_l + ins_r;
1727 th += ins_t + ins_b;
1728 }
1729 else
1730 {
1731 efl_canvas_text_size_native_get(ep->object, NULL, &th);
1732
1733 th += ins_t + ins_b;
1734 }
1735 }
1736 }
1737 else
1738 {
1739 /* text.max: 1 X */
1740 if (chosen_desc->text.min_x)
1741 {
1742 /* text.min: 1 X
1743 * text.max: 1 X
1744 * Singleline. */
1745 efl_canvas_text_size_native_get(ep->object, &tw, &th);
1746
1747 tw += ins_l + ins_r;
1748 th += ins_t + ins_b;
1749 }
1750 else
1751 {
1752 /* text.min: 0 X
1753 * text.max: 1 X */
1754 if (chosen_desc->text.max_y)
1755 {
1756 /* text.min: 0 X
1757 * text.max: 1 1 */
1758 int temp_w, temp_h;
1759
1760 temp_w = TO_INT(params->eval.w);
1761 temp_h = TO_INT(params->eval.h);
1762
1763 if (min_calc_w > temp_w)
1764 temp_w = min_calc_w;
1765 if (min_calc_h > temp_h)
1766 temp_h = min_calc_h;
1767
1768 if (chosen_desc->text.min_y)
1769 {
1770 /* text.min: 0 1
1771 * text.max: 1 1
1772 * There is no need to calculate it again. */
1773 tw = min_calc_w;
1774 th = min_calc_h;
1775 }
1776 else
1777 {
1778 /* text.min: 0 0
1779 * text.max: 1 1 */
1780
1781 efl_gfx_size_set(ep->object, EINA_SIZE2D(temp_w, temp_h));
1782 efl_canvas_text_size_formatted_get(ep->object, &tw, &th);
1783
1784 tw += ins_l + ins_r;
1785 th += ins_t + ins_b;
1786
1787 /* If base width for calculation is 0,
1788 * don't get meaningless height for multiline */
1789 if (temp_w <= 0)
1790 {
1791 efl_canvas_text_size_native_get(ep->object, NULL, &th);
1792
1793 th += ins_t + ins_b;
1794 }
1795 }
1796 }
1797 else
1798 {
1799 /* text.min: 0 X
1800 * text.max: 1 0 */
1801 int temp_w, temp_h;
1802
1803 temp_w = TO_INT(params->eval.w);
1804 if (min_calc_w > temp_w)
1805 temp_w = min_calc_w;
1806
1807 temp_h = efl_gfx_size_get(ep->object).h;
1808 efl_gfx_size_set(ep->object, EINA_SIZE2D(temp_w, temp_h));
1809 efl_canvas_text_size_formatted_get(ep->object, &tw, &th);
1810
1811 tw += ins_l + ins_r;
1812 th += ins_t + ins_b;
1813
1814 /* If base width for calculation is 0,
1815 * don't get meaningless height for multiline */
1816 if (temp_w <= 0)
1817 {
1818 efl_canvas_text_size_native_get(ep->object, NULL, &th);
1819
1820 th += ins_t + ins_b;
1821 }
1822 }
1823 }
1824 }
1825
1826 if (maxw && chosen_desc->text.max_x)
1827 {
1828 if (tw > *maxw) *maxw = tw;
1829 if (minw && (*maxw < *minw)) *maxw = *minw;
1830 }
1831 if (maxh && chosen_desc->text.max_y)
1832 {
1833 if (th > *maxh) *maxh = th;
1834 if (minh && (*maxh < *minh)) *maxh = *minh;
1835 }
1836 }
1837}
1838
1839static void
1840_edje_part_recalc_single_textblock(FLOAT_T sc,
1841 Edje *ed,
1842 Edje_Real_Part *ep,
1843 Edje_Part_Description_Text *chosen_desc,
1844 Edje_Calc_Params *params,
1845 int *minw, int *minh,
1846 int *maxw, int *maxh)
1847{
1848 if ((ep->type != EDJE_RP_TYPE_TEXT) ||
1849 (!ep->typedata.text))
1850 return;
1851
1852 if (chosen_desc)
1853 {
1854 Evas_Coord tw, th;
1855 const char *text = "";
1856 const char *style = "";
1857 Edje_Style *stl = NULL;
1858 const char *tmp;
1859 Eina_List *l;
1860
1861 if (chosen_desc->text.id_source >= 0)
1862 {
1863 Edje_Part_Description_Text *et;
1864
1865 ep->typedata.text->source = ed->table_parts[chosen_desc->text.id_source % ed->table_parts_size];
1866
1867 et = _edje_real_part_text_source_description_get(ep, NULL);
1868 tmp = edje_string_get(&et->text.style);
1869 if (tmp) style = tmp;
1870 }
1871 else
1872 {
1873 ep->typedata.text->source = NULL;
1874
1875 tmp = edje_string_get(&chosen_desc->text.style);
1876 if (tmp) style = tmp;
1877 }
1878
1879 if (chosen_desc->text.id_text_source >= 0)
1880 {
1881 Edje_Part_Description_Text *et;
1882 Edje_Real_Part *rp;
1883
1884 ep->typedata.text->text_source = ed->table_parts[chosen_desc->text.id_text_source % ed->table_parts_size];
1885
1886 et = _edje_real_part_text_text_source_description_get(ep, &rp);
1887 text = edje_string_get(&et->text.text);
1888
1889 if (rp->typedata.text->text) text = rp->typedata.text->text;
1890 }
1891 else
1892 {
1893 ep->typedata.text->text_source = NULL;
1894 text = edje_string_get(&chosen_desc->text.text);
1895 if (ep->typedata.text->text) text = ep->typedata.text->text;
1896 }
1897
1898 EINA_LIST_FOREACH(ed->file->styles, l, stl)
1899 {
1900 if ((stl->name) && (!strcmp(stl->name, style))) break;
1901 stl = NULL;
1902 }
1903
1904 if (ep->part->scale)
1905 evas_object_scale_set(ep->object, TO_DOUBLE(sc));
1906
1907 if ((chosen_desc->text.fit_x) || (chosen_desc->text.fit_y))
1908 {
1909 double base_s = 1.0;
1910 double orig_s;
1911 double s = base_s;
1912
1913 if (ep->part->scale) base_s = TO_DOUBLE(sc);
1914 efl_canvas_object_scale_set(ep->object, base_s);
1915 efl_canvas_text_size_native_get(ep->object, &tw, &th);
1916
1917 orig_s = base_s;
1918 /* Now make it bigger so calculations will be more accurate
1919 * and less influenced by hinting... */
1920 {
1921 orig_s = _edje_part_recalc_single_textblock_scale_range_adjust(chosen_desc, base_s,
1922 orig_s * TO_INT(params->eval.w) / tw);
1923 efl_canvas_object_scale_set(ep->object, orig_s);
1924 efl_canvas_text_size_native_get(ep->object, &tw, &th);
1925 }
1926 if (chosen_desc->text.fit_x)
1927 {
1928 if (tw > 0)
1929 {
1930 s = _edje_part_recalc_single_textblock_scale_range_adjust(chosen_desc, base_s,
1931 orig_s * TO_INT(params->eval.w) / tw);
1932 efl_canvas_object_scale_set(ep->object, s);
1933 efl_canvas_text_size_native_get(ep->object, NULL, NULL);
1934 }
1935 }
1936 if (chosen_desc->text.fit_y)
1937 {
1938 if (th > 0)
1939 {
1940 double tmp_s = _edje_part_recalc_single_textblock_scale_range_adjust(chosen_desc, base_s,
1941 orig_s * TO_INT(params->eval.h) / th);
1942 /* If we already have X fit, restrict Y to be no bigger
1943 * than what we got with X. */
1944 if (!((chosen_desc->text.fit_x) && (tmp_s > s)))
1945 {
1946 s = tmp_s;
1947 }
1948
1949 efl_canvas_object_scale_set(ep->object, s);
1950 efl_canvas_text_size_native_get(ep->object, NULL, NULL);
1951 }
1952 }
1953
1954 /* Final tuning, try going down 90% at a time, hoping it'll
1955 * actually end up being correct. */
1956 {
1957 int i = 5; /* Tries before we give up. */
1958 Evas_Coord fw, fh;
1959 efl_canvas_text_size_native_get(ep->object, &fw, &fh);
1960
1961 /* If we are still too big, try reducing the size to
1962 * 95% each try. */
1963 while ((i > 0) &&
1964 ((chosen_desc->text.fit_x && (fw > TO_INT(params->eval.w))) ||
1965 (chosen_desc->text.fit_y && (fh > TO_INT(params->eval.h)))))
1966 {
1967 double tmp_s = _edje_part_recalc_single_textblock_scale_range_adjust(chosen_desc, base_s, s * 0.95);
1968
1969 /* Break if we are not making any progress. */
1970 if (EQ(tmp_s, s))
1971 break;
1972 s = tmp_s;
1973
1974 efl_canvas_object_scale_set(ep->object, s);
1975 efl_canvas_text_size_native_get(ep->object, &fw, &fh);
1976 i--;
1977 }
1978 }
1979 }
1980
1981 if (stl)
1982 {
1983 if (evas_object_textblock_style_get(ep->object) != stl->style)
1984 evas_object_textblock_style_set(ep->object, stl->style);
1985 // FIXME: need to account for editing
1986 if (ep->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
1987 {
1988 // do nothing - should be done elsewhere
1989 }
1990 else
1991 {
1992 evas_object_textblock_text_markup_set(ep->object, text);
1993 }
1994
1995 if ((ed->file->efl_version.major >= 1) && (ed->file->efl_version.minor >= 19))
1996 {
1997 _edje_part_recalc_single_textblock_min_max_calc(ep,
1998 chosen_desc,
1999 params,
2000 minw, minh,
2001 maxw, maxh);
2002 }
2003 else
2004 {
2005 _edje_part_recalc_single_textblock_min_max_calc_legacy(ep,
2006 chosen_desc,
2007 params,
2008 minw, minh,
2009 maxw, maxh);
2010 }
2011 }
2012
2013 evas_object_textblock_valign_set(ep->object, TO_DOUBLE(chosen_desc->text.align.y));
2014 }
2015}
2016
2017static void
2018_edje_textblock_recalc_apply(Edje *ed, Edje_Real_Part *ep,
2019 Edje_Calc_Params *params,
2020 Edje_Part_Description_Text *chosen_desc)
2021{
2022 /* FIXME: this is just an hack. */
2023 FLOAT_T sc;
2024 sc = DIV(ed->scale, ed->file->base_scale);
2025 if (EQ(sc, ZERO)) sc = DIV(_edje_scale, ed->file->base_scale);
2026 if (chosen_desc->text.fit_x || chosen_desc->text.fit_y)
2027 {
2028 _edje_part_recalc_single_textblock(sc, ed, ep, chosen_desc, params,
2029 NULL, NULL, NULL, NULL);
2030 }
2031}
2032
2033static void 1456static void
2034_edje_part_recalc_single_text(FLOAT_T sc EINA_UNUSED, 1457_edje_part_recalc_single_text(FLOAT_T sc EINA_UNUSED,
2035 Edje *ed, 1458 Edje *ed,