function UTF8_wordwrap($text, $width = 75, $break = "\n", $cut = FALSE) { if ($width <= 0) { $width = 75; } if (is_string($text) && strlen($text) <= $width) { return $text; } // Nothing to do if ($break == '') { $break = "\n"; } $UTF8_text = UTF8_str_split($text); $UTF8_break = UTF8_str_split($break); $UTF8_result = array(); while (UTF8_strlen($UTF8_text) > $width) { $longWord = FALSE; for ($i = $width; $i >= 0; $i--) { if ($UTF8_text[$i] == ' ') { break; } } if ($i < 0) { // We're dealing with a very long word // Not too sure what $cut is supposed to accomplish -- we'll just chop the word $longWord = TRUE; // This means: "not wrapping at a space" $i = $width; } $thisPiece = array_slice($UTF8_text, 0, $i); foreach ($thisPiece as $char) { // Copy front part of input string $UTF8_result[] = $char; } foreach ($UTF8_break as $char) { // Copy separator string $UTF8_result[] = $char; } if (!$longWord) { $i++; } // Skip space at end of piece we've just worked on $UTF8_text = UTF8_substr($UTF8_text, $i); // Remove that piece } foreach ($UTF8_text as $char) { // Copy remainder of input string $UTF8_result[] = $char; } if (is_array($text)) { return $UTF8_result; } return implode('', $UTF8_result); }
function _addName($type, $value, $gedrec) { global $pgv_lang; if (UTF8_strlen($value) < 100) { parent::_addName($type, $value, $gedrec); } else { parent::_addName($type, UTF8_substr($value, 0, 100) . $pgv_lang["ellipsis"], $gedrec); } }
/** * get gedcom tag value * * returns the value of a gedcom tag from the given gedcom record * @param string $tag The tag to find, use : to delineate subtags * @param int $level The gedcom line level of the first tag to find, setting level to 0 will cause it to use 1+ the level of the incoming record * @param string $gedrec The gedcom record to get the value from * @param int $truncate Should the value be truncated to a certain number of characters * @param boolean $convert Should data like dates be converted using the configuration settings * @return string */ function get_gedcom_value($tag, $level, $gedrec, $truncate = '', $convert = true) { global $SHOW_PEDIGREE_PLACES, $pgv_lang; if (empty($gedrec)) { return ""; } $tags = explode(':', $tag); $origlevel = $level; if ($level == 0) { $level = $gedrec[0] + 1; } $subrec = $gedrec; foreach ($tags as $indexval => $t) { $lastsubrec = $subrec; $subrec = get_sub_record($level, "{$level} {$t}", $subrec); if (empty($subrec) && $origlevel == 0) { $level--; $subrec = get_sub_record($level, "{$level} {$t}", $lastsubrec); } if (empty($subrec)) { if ($t == "TITL") { $subrec = get_sub_record($level, "{$level} ABBR", $lastsubrec); if (!empty($subrec)) { $t = "ABBR"; } } if (empty($subrec)) { if ($level > 0) { $level--; } $subrec = get_sub_record($level, "@ {$t}", $gedrec); if (empty($subrec)) { return; } } } $level++; } $level--; $ct = preg_match("/{$level} {$t}(.*)/", $subrec, $match); if ($ct == 0) { $ct = preg_match("/{$level} @.+@ (.+)/", $subrec, $match); } if ($ct == 0) { $ct = preg_match("/@ {$t} (.+)/", $subrec, $match); } if ($ct > 0) { $value = trim($match[1]); $ct = preg_match("/@(.*)@/", $value, $match); if ($ct > 0 && $t != "DATE") { $oldsub = $subrec; switch ($t) { case 'HUSB': case 'WIFE': case 'CHIL': $subrec = find_person_record($match[1]); break; case 'FAMC': case 'FAMS': $subrec = find_family_record($match[1]); break; case 'SOUR': $subrec = find_source_record($match[1]); break; case 'REPO': $subrec = find_other_record($match[1]); break; default: $subrec = find_gedcom_record($match[1]); break; } if ($subrec) { $value = $match[1]; $ct = preg_match("/0 @{$match['1']}@ {$t} (.+)/", $subrec, $match); if ($ct > 0) { $value = $match[1]; $level = 0; } else { $subrec = $oldsub; } } else { //-- set the value to the id without the @ $value = $match[1]; } } if ($level != 0 || $t != "NOTE") { $value .= get_cont($level + 1, $subrec); } $value = preg_replace("'\n'", "", $value); $value = preg_replace("'<br />'", "\n", $value); $value = trim($value); //-- if it is a date value then convert the date if ($convert && $t == "DATE") { $g = new GedcomDate($value); $value = $g->Display(); if (!empty($truncate)) { if (UTF8_strlen($value) > $truncate) { $value = preg_replace("/\\(.+\\)/", "", $value); //if (UTF8_strlen($value)>$truncate) { // $value = preg_replace_callback("/([a-zśź]+)/ui", create_function('$matches', 'return UTF8_substr($matches[1], 0, 3);'), $value); //} } } } else { //-- if it is a place value then apply the pedigree place limit if ($convert && $t == "PLAC") { if ($SHOW_PEDIGREE_PLACES > 0) { $plevels = explode(',', $value); $value = ""; for ($plevel = 0; $plevel < $SHOW_PEDIGREE_PLACES; $plevel++) { if (!empty($plevels[$plevel])) { if ($plevel > 0) { $value .= ", "; } $value .= trim($plevels[$plevel]); } } } if (!empty($truncate)) { if (strlen($value) > $truncate) { $plevels = explode(',', $value); $value = ""; for ($plevel = 0; $plevel < count($plevels); $plevel++) { if (!empty($plevels[$plevel])) { if (strlen($plevels[$plevel]) + strlen($value) + 3 < $truncate) { if ($plevel > 0) { $value .= ", "; } $value .= trim($plevels[$plevel]); } else { break; } } } } } } else { if ($convert && $t == "SEX") { if ($value == "M") { $value = get_first_letter($pgv_lang["male"]); } elseif ($value == "F") { $value = get_first_letter($pgv_lang["female"]); } else { $value = get_first_letter($pgv_lang["unknown"]); } } else { if (!empty($truncate)) { if (strlen($value) > $truncate) { $plevels = explode(' ', $value); $value = ""; for ($plevel = 0; $plevel < count($plevels); $plevel++) { if (!empty($plevels[$plevel])) { if (strlen($plevels[$plevel]) + strlen($value) + 3 < $truncate) { if ($plevel > 0) { $value .= " "; } $value .= trim($plevels[$plevel]); } else { break; } } } } } } } } return $value; } return ""; }
function fillTL($ar, $int, $top) { global $maxX, $zindex, $pgv_lang, $factarray, $factAbbrev; $zindex = count($ar); $rows = array(); $modFix = 0; if ($this->modTest == 1) { $modFix = 9 * $this->birthMod; } //base case if (count($ar) == 0) { return $top; } $maxY = $top; foreach ($ar as $key => $value) { //Creates appropriate color scheme to show relationships $this->currentsex = $value->getSex(); if ($this->currentsex == "M") { $this->Mcolorindex++; if (!isset($this->malecolorR[$this->Mcolorindex])) { $this->Mcolorindex = 0; } $this->malecolorR[$this->Mcolorindex]; $this->Mcolorindex++; if (!isset($this->malecolorG[$this->Mcolorindex])) { $this->Mcolorindex = 0; } $this->malecolorG[$this->Mcolorindex]; $red = dechex($this->malecolorR[$this->Mcolorindex]); $green = dechex($this->malecolorR[$this->Mcolorindex]); if (strlen($red) < 2) { $red = "0" . $red; } if (strlen($green) < 2) { $green = "0" . $green; } $this->color = "#" . $red . $green . dechex($this->malecolorB); } else { if ($this->currentsex == "F") { $this->Fcolorindex++; if (!isset($this->femalecolorG[$this->Fcolorindex])) { $this->Fcolorindex = 0; } $this->femalecolorG[$this->Fcolorindex]; $this->Fcolorindex++; if (!isset($this->femalecolorB[$this->Fcolorindex])) { $this->Fcolorindex = 0; } $this->femalecolorB[$this->Fcolorindex]; $this->color = "#" . dechex($this->femalecolorR) . dechex($this->femalecolorG[$this->Fcolorindex]) . dechex($this->femalecolorB[$this->Fcolorindex]); } else { $this->color = $this->colors[$this->colorindex]; } } //set start position and size of person-box according to zoomfactor /* @var $value Person */ $bdate = $value->getEstimatedBirthDate(); $ddate = $value->getEstimatedDeathDate(); $birthYear = $bdate->gregorianYear(); $deathYear = $ddate->gregorianYear() ? $ddate->gregorianYear() : date('Y'); $width = ($deathYear - $birthYear) * $this->zoomfactor; $height = 2 * $this->zoomfactor; $startPos = ($birthYear - $this->timelineMinYear) * $this->zoomfactor + 14 + $modFix; if (stristr($value->getFullName(), "starredname")) { $minlength = (UTF8_strlen($value->getFullName()) - 34) * $this->zoomfactor; } else { $minlength = UTF8_strlen($value->getFullName()) * $this->zoomfactor; } if ($startPos > 15) { $startPos = ($birthYear - $this->timelineMinYear) * $this->zoomfactor + 15 + $modFix; $startPos = ($birthYear - $this->timelineMinYear) * $this->zoomfactor + 15; $width = ($deathYear - $birthYear) * $this->zoomfactor - 2; } //set start position to deathyear $int = $deathYear; //set minimum width for single year lifespans if ($width < 10) { $width = 10; $int = $birthYear + 1; } $lifespan = "<span dir=\"ltr\">{$birthYear}-</span>"; $deathReal = $value->getDeathDate()->isOK(); $birthReal = $value->getBirthDate()->isOK(); if ($value->isDead() && $deathReal) { $lifespan .= "<span dir=\"ltr\">{$deathYear}</span>"; } $lifespannumeral = $deathYear - $birthYear; //-- calculate a good Y top value $Y = $top; $Z = $zindex; $ready = false; while (!$ready) { if (!isset($rows[$Y])) { $ready = true; $rows[$Y]["x1"] = $startPos; $rows[$Y]["x2"] = $startPos + $width; $rows[$Y]["z"] = $zindex; } else { if ($rows[$Y]["x1"] > $startPos + $width) { $ready = true; $rows[$Y]["x1"] = $startPos; $Z = $rows[$Y]["z"]; } else { if ($rows[$Y]["x2"] < $startPos) { $ready = true; $rows[$Y]["x2"] = $startPos + $width; $Z = $rows[$Y]["z"]; } else { //move down 25 pixels if ($this->zoomfactor > 10) { $Y += 25 + $this->zoomfactor; } else { $Y += 25; } } } } } //Need to calculate each event and the spacing between them // event1 distance will be event - birthyear that will be the distance. then each distance will chain off that //$event[][] = {"Cell 1 will hold events"}{"cell2 will hold time between that and the next value"}; //$value->add_historical_facts(); $value->add_family_facts(false); $unparsedEvents = $value->getIndiFacts(); sort_facts($unparsedEvents); $eventinformation = array(); $eventspacing = array(); foreach ($unparsedEvents as $index => $val) { $date = $val->getDate(); if (!empty($date)) { $fact = $val->getTag(); $yearsin = $date->date1->y - $birthYear; if ($lifespannumeral == 0) { $lifespannumeral = 1; } $eventwidth = $yearsin / $lifespannumeral * 100; // percent of the lifespan before the event occured used for determining div spacing // figure out some schema $evntwdth = $eventwidth . "%"; //-- if the fact is a generic EVENt then get the qualifying TYPE if ($fact == "EVEN") { $fact = $val->getType(); } $place = $val->getPlace(); $trans = $fact; if (isset($factarray[$fact])) { $trans = $factarray[$fact]; } else { if (isset($pgv_lang[$fact])) { $trans = $pgv_lang[$fact]; } } if (isset($eventinformation[$evntwdth])) { $eventinformation[$evntwdth] .= "<br />\n" . $trans . "<br />\n" . strip_tags($date->Display(false, '', NULL, false)) . " " . $place; } else { $eventinformation[$evntwdth] = $fact . "-fact," . $trans . "<br />\n" . strip_tags($date->Display(false, '', NULL, false)) . " " . $place; } } } $bdate = $value->getEstimatedBirthDate(); $ddate = $value->getEstimatedDeathDate(); if ($width > $minlength + 110) { echo "\n<div id=\"bar_" . $value->getXref() . "\" style=\"position: absolute; top:" . $Y . "px; left:" . $startPos . "px; width:" . $width . "px; height:" . $height . "px; background-color:" . $this->color . "; border: solid blue 1px; z-index:{$Z};\">"; foreach ($eventinformation as $evtwidth => $val) { print "<div style=\"position:absolute; left:" . $evtwidth . ";\"><a class=\"showit\" href=\"#\" style=\"top:-2px; font-size:10px;\"><b>"; $text = explode("-fact,", $val); $fact = $text[0]; $val = $text[1]; if (isset($factAbbrev[$fact])) { print $factAbbrev[$fact]; } else { print get_first_letter($val); } print "</b><span>" . PrintReady($val) . "</span></a></div>"; } $indiName = PrintReady(str_replace(array('<span class="starredname">', '</span>'), array('<u>', '</u>'), $value->getFullName())); print "\n\t<table><tr>\n\t\t<td width=\"15\"><a class=\"showit\" href=\"#\"><b>"; if (isset($factAbbrev["BIRT"])) { print $factAbbrev["BIRT"]; } else { print get_first_letter($factarray["BIRT"]); } if (!$birthReal) { print "*"; } print "</b><span>" . $value->getSexImage() . $indiName . "<br/>" . $factarray["BIRT"] . " " . strip_tags($bdate->Display(false)) . " " . PrintReady($value->getBirthPlace()) . "</span></a></td>" . "\n\t\t<td align=\"left\" width=\"100%\"><a href=\"" . encode_url($value->getLinkUrl()) . "\">" . $value->getSexImage() . $indiName . ": {$lifespan} </a></td>" . "\n\t\t<td width=\"15\">"; if ($value->isDead()) { if ($deathReal || $value->isDead()) { print "<a class=\"showit\" href=\"#\"><b>"; if (isset($factAbbrev["DEAT"])) { print $factAbbrev["DEAT"]; } else { print get_first_letter($factarray["DEAT"]); } if (!$deathReal) { print "*"; } print "</b><span>" . $value->getSexImage() . $indiName . "<br/>" . $factarray["DEAT"] . " " . strip_tags($ddate->Display(false)) . " " . PrintReady($value->getDeathPlace()) . "</span></a>"; } } print "</td></tr></table>"; echo '</div>'; } else { if ($width > $minlength + 5) { echo "\n<div style=\"text-align: left; position: absolute; top:" . $Y . "px; left:" . $startPos . "px; width:" . $width . "px; height:" . $height . "px; background-color:" . $this->color . "; border: solid blue 1px; z-index:{$Z};\">"; foreach ($eventinformation as $evtwidth => $val) { print "<div style=\"position:absolute; left:" . $evtwidth . " \"><a class=\"showit\" href=\"#\" style=\"top:-2px; font-size:10px;\"><b>"; $text = explode("-fact,", $val); $fact = $text[0]; $val = $text[1]; if (isset($factAbbrev[$fact])) { print $factAbbrev[$fact]; } else { print get_first_letter($val); } print "</b><span>" . PrintReady($val) . "</span></a></div>"; } $indiName = PrintReady(str_replace(array('<span class="starredname">', '</span>'), array('<u>', '</u>'), $value->getFullName())); print "\n\t<table dir=\"ltr\"><tr>\n\t\t<td width=\"15\"><a class=\"showit\" href=\"#\"><b>"; if (isset($factAbbrev["BIRT"])) { print $factAbbrev["BIRT"]; } else { print get_first_letter($factarray["BIRT"]); } if (!$birthReal) { print "*"; } print "</b><span>" . $value->getSexImage() . $indiName . "<br/>" . $factarray["BIRT"] . " " . strip_tags($bdate->Display(false)) . " " . PrintReady($value->getBirthPlace()) . "</span></a></td>" . "<td align=\"left\" width=\"100%\"><a href=\"" . encode_url($value->getLinkUrl()) . "\">" . $value->getSexImage() . $indiName . "</a></td>" . "\n\t\t<td width=\"15\">"; if ($value->isDead()) { if ($deathReal || $value->isDead()) { print "<a class=\"showit\" href=\"#\"><b>"; if (isset($factAbbrev["DEAT"])) { print $factAbbrev["DEAT"]; } else { print get_first_letter($factarray["DEAT"]); } if (!$deathReal) { print "*"; } print "</b><span>" . $value->getSexImage() . $indiName . "<br/>" . $factarray["DEAT"] . " " . strip_tags($ddate->Display(false)) . " " . PrintReady($value->getDeathPlace()) . "</span></a>"; } } print "</td></tr></table>"; echo '</div>'; } else { echo "\n<div style=\"text-align: left; position: absolute;top:" . $Y . "px; left:" . $startPos . "px;width:" . $width . "px; height:" . $height . "px; background-color:" . $this->color . "; border: solid blue 1px; z-index:{$Z};\">"; $indiName = PrintReady(str_replace(array('<span class="starredname">', '</span>'), array('<u>', '</u>'), $value->getFullName())); print "<a class=\"showit\" href=\"" . encode_url($value->getLinkUrl()) . "\"><b>"; if (isset($factAbbrev["BIRT"])) { print $factAbbrev["BIRT"]; } else { print get_first_letter($factarray["BIRT"]); } if (!$birthReal) { print "*"; } print "</b><span>" . $value->getSexImage() . $indiName . "<br/>" . $factarray["BIRT"] . " " . strip_tags($bdate->Display(false)) . " " . PrintReady($value->getBirthPlace()) . "<br/>"; foreach ($eventinformation as $evtwidth => $val) { $text = explode("-fact,", $val); $val = $text[1]; print $val . "<br />\n"; } if ($value->isDead() && $deathReal) { print $factarray["DEAT"] . " " . strip_tags($ddate->Display(false)) . " " . PrintReady($value->getDeathPlace()); } print "</span></a>"; echo '</div>'; } } $zindex--; if ($maxX < $startPos + $width) { $maxX = $startPos + $width; } if ($maxY < $Y) { $maxY = $Y; } } return $maxY; }
function getStringWidth($text) { $style = $this->getStyle($this->currentStyle); return UTF8_strlen($text) * ($style['size'] / 2); }
/** * @todo add info * @param array $attrs an array of key value pairs for the attributes */ function PGVRGetPersonNameSHandler($attrs) { global $currentElement, $vars, $gedrec, $gedrecStack, $pgv_lang, $SHOW_ID_NUMBERS; $id = ""; if (empty($attrs["id"])) { $match = array(); $ct = preg_match("/0 @(.+)@/", $gedrec, $match); if ($ct > 0) { $id = $match[1]; } } else { $match = array(); $ct = preg_match("/\\\$(.+)/", $attrs["id"], $match); if ($ct > 0) { if (isset($vars[$match[1]]["id"])) { $id = $vars[$match[1]]["id"]; } } else { $ct = preg_match("/@(.+)/", $attrs["id"], $match); if ($ct > 0) { $gmatch = array(); $gt = preg_match("/\\d {$match['1']} @([^@]+)@/", $gedrec, $gmatch); //print $gt; if ($gt > 0) { $id = $gmatch[1]; //print "[$id]"; } } else { $id = $attrs["id"]; } } } if (!empty($id)) { $record = GedcomRecord::getInstance($id); if (is_null($record)) { return; } if (!$record->canDisplayDetails()) { $currentElement->addText($pgv_lang["private"]); } else { $name = $record->getFullName(); $name = preg_replace("/<span class=\"starredname\">(.*)<\\/span> ?/", "\\1* ", $name); //restores the * for underlining a given name $name = strip_tags($name); if (!empty($attrs["truncate"])) { //short-circuit with the faster strlen if (strlen($name) > $attrs["truncate"] && UTF8_strlen($name) > $attrs["truncate"]) { $name = preg_replace("/\\(.*\\) ?/", "", $name); //removes () and text inbetween - what about ", [ and { etc? } if (strlen($name) > $attrs["truncate"] && UTF8_strlen($name) > $attrs["truncate"]) { $words = explode(' ', $name); $name = $words[count($words) - 1]; for ($i = count($words) - 2; $i >= 0; $i--) { $len = UTF8_strlen($name); for ($j = count($words) - 3; $j >= 0; $j--) { $len += UTF8_strlen($words[$j]); } if ($len > $attrs["truncate"]) { $first_letter = get_first_letter($words[$i]); //do not show " of nick-names if ($first_letter != '"') { $name = get_first_letter($words[$i]) . ". " . $name; } } else { $name = $words[$i] . " " . $name; } } } } else { $addname = $record->getAddName(); if (!empty($addname)) { $name .= " " . $addname; } } $currentElement->addText(trim($name)); } } }