#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
int
*
hex_to_array(str)
char
* str;
{
int
*a;
int
i, j, n, v;
n =
strlen
(str) / 8;
New(0, a, n,
int
);
for
(i = 0; i < n; i++) {
v = 0;
for
(j = 0; j < 8; j++) {
v = v << 4;
if
(str[i*8 + j] >=
'a'
) {
v = v + str[i*8 + j] -
'a'
+ 10;
}
else
{
v = v + str[i*8 + j] -
'0'
;
}
}
a[i] = v;
}
return
(a);
}
char
*
array_to_hex(a, n)
int
* a;
int
n;
{
char
*res;
char
s[9];
int
i;
New(0, res, n * 8 + 1,
char
);
res[0] = 0;
for
(i = 0; i < n; i++) {
sprintf
(s,
"%08x"
, a[i]);
strcat
(res, s);
}
return
(res);
}
char
*
reflow_trial(optimum_c, maximum, wordcount,
penaltylimit, semantic, shortlast,
word_len_c, space_len_c, extra_c,
result)
int
maximum, wordcount, penaltylimit, semantic, shortlast;
char
*optimum_c, *word_len_c, *space_len_c, *extra_c;
char
*result;
{
int
*optimum, *word_len, *space_len, *extra;
int
*linkbreak, *totalpenalty, *best_linkbreak;
int
lastbreak, i, j, k, interval, penalty, bestsofar;
int
best_lastbreak, opt;
char
*best_linkbreak_c;
int
opts, ii, count;
int
best = penaltylimit * 21;
optimum = hex_to_array(optimum_c);
word_len = hex_to_array(word_len_c);
space_len = hex_to_array(space_len_c);
extra = hex_to_array(extra_c);
count = wordcount *
sizeof
(
int
);
New(0, linkbreak, count,
int
);
New(0, totalpenalty, count,
int
);
New(0, best_linkbreak, count,
int
);
best_lastbreak = 0;
opts =
strlen
(optimum_c) / 8;
for
(i = 0; i < opts; i++) {
opt = optimum[i];
for
(j = 0; j < wordcount; j++) {
interval = 0;
totalpenalty[j] = penaltylimit * 2;
for
(k = j; k >= 0; k--) {
interval += word_len[k];
if
((k < j) && ((interval > opt + 10)
|| (interval >= maximum))) {
break
;
}
penalty = (interval - opt) * (interval - opt);
interval += space_len[k];
if
(k > 0) {
penalty += totalpenalty[k-1];
}
penalty -= (extra[j] * semantic)/2;
if
(penalty < totalpenalty[j]) {
totalpenalty[j] = penalty;
linkbreak[j] = k-1;
}
}
}
interval = 0;
bestsofar = penaltylimit * 20;
lastbreak = wordcount-2;
for
(k = wordcount-2; k >= -1; k--) {
interval += word_len[k+1];
if
((interval > opt + 10) || (interval > maximum)) {
break
;
}
if
(interval > opt) {
penalty = (interval - opt) * (interval - opt);
}
else
{
penalty = 0;
}
interval += space_len[k+1];
if
(k >= 0) {
penalty += totalpenalty[k];
}
if
(wordcount - k - 1 <= 2) {
penalty += shortlast * semantic;
}
if
(penalty <= bestsofar) {
bestsofar = penalty;
lastbreak = k;
}
}
if
(bestsofar < best) {
best_lastbreak = lastbreak;
for
(ii = 0; ii < wordcount; ii++) {
best_linkbreak[ii] = linkbreak[ii];
}
best = bestsofar;
}
}
best_linkbreak_c = array_to_hex(best_linkbreak, wordcount);
sprintf
(result,
"%08x"
, best_lastbreak);
strcat
(result, best_linkbreak_c);
Safefree(optimum);
Safefree(word_len);
Safefree(space_len);
Safefree(extra);
Safefree(linkbreak);
Safefree(totalpenalty);
Safefree(best_linkbreak);
Safefree(best_linkbreak_c);
return
(result);
}
MODULE = Text::Reflow PACKAGE = Text::Reflow
char
*
reflow_trial(optimum, maximum, wordcount, \
penaltylimit, semantic, shortlast, \
word_len, space_len, extra, result)
int
maximum
int
wordcount
int
penaltylimit
int
semantic
int
shortlast
char
* optimum
char
* word_len
char
* space_len
char
* extra
char
* result
PROTOTYPE: $$$$$$$$$$
OUTPUT:
result