📄 reflow.xs
字号:
#include "EXTERN.h"#include "perl.h"#include "XSUB.h"/* convert a hex string to an array of ints */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);}/* Pack an array of ints into a hex string */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); /* Keep gcc -Wall happy: */ best_lastbreak = 0; /* size of optimum array: */ 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; /* Pick a break for the last line which gives */ /* the least penalties for previous lines: */ 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; } } /* Save these breaks if they are an improvement: */ if (bestsofar < best) { best_lastbreak = lastbreak; for (ii = 0; ii < wordcount; ii++) { best_linkbreak[ii] = linkbreak[ii]; } best = bestsofar; } } /* Return the best breaks, */ /* ie return the array ($best_lastbreak, @best_linkbreak) as a hex string */ 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -